def test_polarization_vidale(self): st = _create_test_data() t = st[0].stats.starttime e = st[0].stats.endtime out = polarization.polarization_analysis(st, win_len=10.0, win_frac=0.1, frqlow=1.0, frqhigh=5.0, verbose=False, stime=t, etime=e, method="vidale", var_noise=0.0) # all values should be equal for the test data, so check first value # and make sure all values are almost equal self.assertEqual(out["timestamp"][0], 1393632003.0) self.assertAlmostEqual(out["azimuth"][0], 26.56505117707799) self.assertAlmostEqual(out["incidence"][0], 65.905157447889309) self.assertAlmostEqual(out["rectilinearity"][0], 1.000000) self.assertAlmostEqual(out["planarity"][0], 1.000000) self.assertAlmostEqual(out["ellipticity"][0], 3.8195545129768958e-06) for key in [ "azimuth", "incidence", "rectilinearity", "planarity", "ellipticity" ]: got = out[key] self.assertTrue( np.allclose(got / got[0], np.ones_like(got), rtol=1e-4)) self.assertTrue( np.allclose(out["timestamp"] - out["timestamp"][0], np.arange(0, 97.85, 0.05), rtol=1e-5))
def test_polarization_pm(self): st = _create_test_data() t = st[0].stats.starttime e = st[0].stats.endtime out = polarization.polarization_analysis(st, win_len=10.0, win_frac=0.1, frqlow=1.0, frqhigh=5.0, verbose=False, stime=t, etime=e, method="pm", var_noise=0.0) # all values should be equal for the test data, so check first value # and make sure all values are almost equal self.assertEqual(out["timestamp"][0], 1393632001.0) self.assertAlmostEqual(out["azimuth"][0], 26.56505117707799) self.assertAlmostEqual(out["incidence"][0], 65.905157447889309) self.assertAlmostEqual(out["azimuth_error"][0], 0.000000) self.assertAlmostEqual(out["incidence_error"][0], 0.000000) for key in ["azimuth", "incidence"]: got = out[key] self.assertTrue( np.allclose(got / got[0], np.ones_like(got), rtol=1e-4)) for key in ["azimuth_error", "incidence_error"]: got = out[key] expected = np.empty_like(got) expected.fill(got[0]) self.assertTrue(np.allclose(got, expected, rtol=1e-4, atol=1e-16)) self.assertTrue( np.allclose(out["timestamp"] - out["timestamp"][0], np.arange(0, 92, 1)))
def test_polarization_pm(self): st = _create_test_data() t = st[0].stats.starttime e = st[0].stats.endtime out = polarization.polarization_analysis( st, win_len=10.0, win_frac=0.1, frqlow=1.0, frqhigh=5.0, verbose=False, stime=t, etime=e, method="pm", var_noise=0.0) # all values should be equal for the test data, so check first value # and make sure all values are almost equal self.assertEqual(out["timestamp"][0], 1393632001.0) self.assertAlmostEqual(out["azimuth"][0], 26.56505117707799) self.assertAlmostEqual(out["incidence"][0], 65.905157447889309) self.assertAlmostEqual(out["azimuth_error"][0], 0.000000) self.assertAlmostEqual(out["incidence_error"][0], 0.000000) for key in ["azimuth", "incidence"]: got = out[key] assert_allclose(got / got[0], np.ones_like(got), rtol=1e-4) for key in ["azimuth_error", "incidence_error"]: got = out[key] expected = np.empty_like(got) expected.fill(got[0]) assert_allclose(got, expected, rtol=1e-4, atol=1e-16) assert_allclose(out["timestamp"] - out["timestamp"][0], np.arange(0, 92, 1))
def test_polarization_vidale(self): st = _create_test_data() t = st[0].stats.starttime e = st[0].stats.endtime out = polarization.polarization_analysis( st, win_len=10.0, win_frac=0.1, frqlow=1.0, frqhigh=5.0, verbose=False, stime=t, etime=e, method="vidale", var_noise=0.0) # all values should be equal for the test data, so check first value # and make sure all values are almost equal self.assertEqual(out["timestamp"][0], 1393632003.0) self.assertAlmostEqual(out["azimuth"][0], 26.56505117707799) self.assertAlmostEqual(out["incidence"][0], 65.905157447889309) self.assertAlmostEqual(out["rectilinearity"][0], 1.000000) self.assertAlmostEqual(out["planarity"][0], 1.000000) self.assertAlmostEqual(out["ellipticity"][0], 3.8195545129768958e-06) for key in ["azimuth", "incidence", "rectilinearity", "planarity", "ellipticity"]: got = out[key] self.assertTrue(np.allclose(got / got[0], np.ones_like(got), rtol=1e-4)) self.assertTrue(np.allclose(out["timestamp"] - out["timestamp"][0], np.arange(0, 97.85, 0.05), rtol=1e-5))
def test_polarization_flinn(self): st = _create_test_data() t = st[0].stats.starttime e = st[0].stats.endtime out = polarization.polarization_analysis( st, win_len=10.0, win_frac=0.1, frqlow=1.0, frqhigh=5.0, verbose=False, timestamp='mlabday', stime=t, etime=e, method="flinn", var_noise=0.0) self.assertAlmostEqual(out["azimuth"], 26.56505117707799) self.assertAlmostEqual(out["incidence"], 65.905157447889309) self.assertAlmostEqual(out["rectilinearity"], 1.000000) self.assertAlmostEqual(out["planarity"], 1.000000)
def polarize(self, t1: UTCDateTime, t2: UTCDateTime, win_len, frqlow, frqhigh, method='flinn'): # win_frac=int(win_len*win_frac/100) st = self.__get_stream(t1, t2) fs = st[0].stats.sampling_rate win_frac = 1 / (fs * win_len) out = polarization_analysis(st, win_len, win_frac, frqlow, frqhigh, st[0].stats.starttime, st[0].stats.endtime, verbose=False, method=method, var_noise=0.0) time = out["timestamp"] azimuth = out["azimuth"] + 180 incident_angle = out["incidence"] planarity = out["planarity"] rectilinearity = out["rectilinearity"] #time=np.arange(0,len(azimuth)) variables = { 'time': time, 'azimuth': azimuth, 'incident_angle': incident_angle, 'planarity': planarity, 'rectilinearity': rectilinearity } return variables
def WavePicking(st, T, SecondP, SecondS, plot): """ P and S Phase picking -input: -st : stream contain the 3 component of the signal -T : float, 5s time of the sliding windows see baillard but could be change trial shoaw goiod result with 5s. -plot: bool, if true plot will be draw -SecondP, float theorical P arrival in second -Seconds,float theorical S arrival in second -output - minF4p: float, coordiantes of the p start in second - minF4s: float, coordiantes of the s start in second calculating using the kitosis derived function and rectilinearity -exemple: minF4p, minF4s = WavePicking3(st_copy,5, 0,10,True) """ # initialisation~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ st = st.copy() trZ = st.select(component='Z')[0] trN = st.select(component='E')[0] df = trZ.stats.sampling_rate tr_copy = trZ.copy() trN_copy = trN.copy() tr_copy2 = trZ.copy() P_Sdelay = (SecondS - SecondP) # Trim signal ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if SecondP > 60 * 5: a = trZ.stats.starttime tr_copy.trim(starttime=a + SecondP - 60) trN_copy.trim(starttime=a + SecondP - 60) SecondP = SecondP - 60 if tr_copy.stats.endtime - tr_copy.stats.starttime > 10 * 60: trN_copy.trim(endtime=a + SecondP + 60 * 10) tr_copy.trim(endtime=a + SecondP + 60 * 10) st.trim(endtime=a + SecondP + 60 * 10) elif tr_copy.stats.endtime - tr_copy.stats.starttime > 10 * 60: a = trZ.stats.starttime trN_copy.trim(endtime=a + SecondP + 60 * 10) tr_copy.trim(endtime=a + SecondP + 60 * 10) st.trim(endtime=a + SecondP + 60 * 10) # P phase arrival picking~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Cf = CFkurtosis(tr_copy, T) f2 = F2(Cf) f3 = F3(f2) f3mean = MeanF3(f3, 0.5) #sliding windows of 0.5 s show good results f4 = F4(f3mean) f4prim = F4prim(f4) # S phase arrival picking~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CfN = CFkurtosis(trN_copy, T) f2N = F2(CfN) f3N = F3(f2N) f3meanN = MeanF3(f3N, 0.5) #sliding windows of 0.5 s show good results f4N = F4(f3meanN) f4primN = F4prim(f4N) #polarisation analysis ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ start1 = trN_copy.stats['starttime'] for tr in st: start = tr.stats['starttime'] if start > start1: start1 = start pol = polarization_analysis(st, 5, 0.1, 0.1, 20, start1, trN_copy.stats['endtime'], verbose=False, method='flinn', var_noise=0.0) rectilinearity = pol['rectilinearity'] incidence = pol['incidence'] rectilinearity2 = scipy.signal.resample(rectilinearity, len(f4prim), axis=0) incidence2 = scipy.signal.resample(incidence, len(f4prim), axis=0) #P S filter cf Ross 2016 sfilter, pfilter = PSswavefilter(rectilinearity2, incidence2) tr_copyS = trN_copy.copy() tr_copyP = tr_copy.copy() tr_copyS = tr_copyS.data * sfilter tr_copyP = tr_copyP.data * pfilter # P and S wave picking ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ minF4p = 100 * 2 + np.argmin( f4prim[100 * 2:len(f4prim) - 100 * 2]) #avoisd to point the end and begin of the siganl! if sfilter[ minF4p] > 0.4: #NOT A p WAVE HD/Working/WavePicking_%s.png'%component,dpi=300) LminF4p2 = np.argwhere( (f4prim[100 * 2:len(f4prim) - 100 * 2] < 0.01 * minF4p) & (sfilter[100 * 2:len(f4prim) - 100 * 2] < 0.4)) if len(LminF4p2) <> 0: Minp = LminF4p2[0] for Min in LminF4p2: if f4prim[Min] <= f4prim[Minp]: Minp = Min minF4p = 100 * 2 + Minp # P picking if isinstance(minF4p, (list, tuple, np.ndarray)) == True: minF4p = minF4p[0] min2F4s2 = np.argmin(f4primN[minF4p + (1 - 0.20) * P_Sdelay * 100:minF4p + (1 - 0.20) * P_Sdelay * 100 + 60 * 100]) minF4s2 = minF4p + (1 - 0.20) * P_Sdelay * 100 + min2F4s2 if sfilter[minF4s2] < 0.25: #NOT A S WAVE S limite LminF4s2 = np.argwhere( (f4primN[minF4p + (1 - 0.20) * P_Sdelay * 100:minF4p + (1 - 0.20) * P_Sdelay * 100 + 15 * 100] < 0.2 * f4primN[minF4s2])) if len(LminF4s2) <> 0: Mins = LminF4s2[0] for Min in LminF4s2: if f4prim[Min] <= f4prim[Mins]: Mins = Min minF4s2 = minF4p + (1 - 0.20) * P_Sdelay * 100 + Mins if isinstance(minF4s2, (list, tuple, np.ndarray)) == True: minF4s2 = minF4s2[0] # plot ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if plot == True: component = trZ.stats.channel f, (ax0, ax1, ax2, ax3, ax4, ax5, ax6, ax7) = plt.subplots(8, sharex=True) x = range(len(tr_copy.data)) ax0.plot(x, trN_copy.data) ax0.axvline(x=minF4p, color='r') ax0.axvline(x=minF4s2, color='aqua') ax0.set_ylabel('$velocity m.s^-1$') ax1.plot(x, Cf) ax1.plot(x, CfN) ax1.axvline(x=minF4p, color='r') ax1.axvline(x=minF4s2, color='aqua') ax1.set_ylabel('$Cf$') ax2.plot(x, f2) ax2.axvline(x=minF4p, color='r') ax2.axvline(x=minF4s2, color='aqua') ax2.set_ylabel('$F2$') ax3.plot(x, f3meanN) ax3.set_ylabel('$F3$') ax3.axvline(x=minF4p, color='r') ax3.axvline(x=minF4s2, color='aqua') ax4.axvline(x=minF4p, color='r') ax4.axvline(x=minF4s2, color='aqua') ax4.plot(x, f4prim) ax4.plot(x, f4primN) ax4.set_ylabel('$F4$') ax5.plot(x, sfilter) ax5.axvline(x=minF4p, color='r') ax5.axvline(x=minF4s2, color='aqua') ax5.set_ylabel('$sfilter$') ax6.plot(x, pfilter) ax6.axvline(x=minF4p, color='r') ax6.axvline(x=minF4s2, color='aqua') ax6.set_ylabel('$pfilter$') ax7.plot(trN_copy, 'k') ax7.plot(tr_copyS, 'b') ax7.plot(tr_copyP, 'r') ax7.axvline(x=minF4p, color='r') ax7.axvline(x=minF4s2, color='aqua') ax0.set_title('tr' + component + ' Windows time ' + str(T) + 's') return SecondP + minF4p / df, SecondP + minF4s2 / df
def selectorPlot(self): roi = self.selector[0].getRegion() if 1 < np.abs(roi[1] - roi[0]) < 30 or \ (1 < np.abs(roi[1] - roi[0]) and \ (self.plot_type.currentText() == 'Azimuth Window' or \ self.plot_type.currentText() == 'Jurkevic Azimuth') or \ self.plot_type.currentText() == 'Azimuth Colourmap'): ### TEMP stime = UTCDateTime(self.bam.setup.fireball_datetime) + roi[0] etime = UTCDateTime(self.bam.setup.fireball_datetime) + roi[1] win_len = float(self.win_len_e.text()) win_frac = float(self.win_frac_e.text()) try: pol_res = polarization_analysis(self.condensed_stream, win_len, win_frac, \ float(self.low_edits.text()), float(self.high_edits.text()), stime, etime, adaptive=True) except ValueError: pol_res = {} pol_res['azimuth'] = np.nan pol_res['timestamp'] = np.nan except IndexError: pol_res = {} pol_res['azimuth'] = np.nan pol_res['timestamp'] = np.nan print( "Too many indicies for array - Not sure on this error yet") self.particle_motion_canvas.clear() self.waveform_canvas.clear() self.waveform_fft_canvas.clear() st_data = [None] * 3 ti_data = [None] * 3 raw_data = [None] * 3 noise_data = [None] * 3 for i in range(len(self.condensed_stream)): st = self.condensed_stream[i].copy() stn = self.stn delta = st.stats.delta start_datetime = st.stats.starttime.datetime end_datetime = st.stats.endtime.datetime stn.offset = ( start_datetime - self.bam.setup.fireball_datetime).total_seconds() self.current_waveform_delta = delta self.current_waveform_time = np.arange(0, st.stats.npts / st.stats.sampling_rate, \ delta) time_data = np.copy(self.current_waveform_time) st.detrend() resp = stn.response st2 = st.copy() st2 = st2.remove_response(inventory=resp, output="DISP") # st2.remove_sensitivity(resp) waveform_data = st2.data waveform_data = waveform_data[:len(time_data)] time_data = time_data[:len(waveform_data)] + stn.offset self.current_waveform_processed = waveform_data number_of_pts_per_s = st.stats.sampling_rate len_of_region = roi[1] - roi[0] num_of_pts_in_roi = len_of_region * number_of_pts_per_s num_of_pts_in_offset = np.abs(number_of_pts_per_s * stn.offset) num_of_pts_to_roi = roi[0] * number_of_pts_per_s pt_0 = int(num_of_pts_in_offset + num_of_pts_to_roi) pt_1 = int(pt_0 + num_of_pts_in_roi) raw_data[i] = waveform_data[pt_0:pt_1] noise_data[i] = waveform_data[0:(pt_1 - pt_0)] ##### # Bandpass ##### low = float(self.low_edits.text()) high = float(self.high_edits.text()) if low > 0 and high > 0: # Init the butterworth bandpass filter butter_b, butter_a = butterworthBandpassFilter(low, high, \ 1.0/self.current_waveform_delta, order=2) # Filter the data waveform_data = scipy.signal.filtfilt( butter_b, butter_a, np.copy(waveform_data)) # waveform_data = st.data # butter_b, butter_a = butterworthBandpassFilter(float(self.low_edits.text()), float(self.high_edits.text()), \ # 1.0/self.current_waveform_delta, order=6) # # Filter the data # waveform_data = scipy.signal.filtfilt(butter_b, butter_a, np.copy(waveform_data)) st_data[i] = waveform_data[pt_0:pt_1] ti_data[i] = time_data[pt_0:pt_1] e_r, n_r, z_r = raw_data[0], raw_data[1], raw_data[2] e_n, n_n, z_n = noise_data[0], noise_data[1], noise_data[2] e, n, z = st_data[0], st_data[1], st_data[2] et, nt, zt = ti_data[0], ti_data[1], ti_data[2] e = np.array(e) n = np.array(n) def fit_func(beta, x): return beta[0] * x data = scipy.odr.Data(e, n) model = scipy.odr.Model(fit_func) odr = scipy.odr.ODR(data, model, beta0=[1.0]) out = odr.run() az_slope = out.beta[0] az_error = out.sd_beta[0] azimuth = np.arctan2(1.0, az_slope) az_error = np.degrees(1.0 / ((1.0**2 + az_slope**2) * azimuth) * az_error) z = np.array(z) r = np.sqrt(n**2 + e**2) * np.cos(azimuth - np.arctan2(n, e)) data = scipy.odr.Data(r, z) model = scipy.odr.Model(fit_func) odr = scipy.odr.ODR(data, model, beta0=[1.0]) out = odr.run() in_slope = out.beta[0] in_error = out.sd_beta[0] x_h, y_h = np.abs(scipy.signal.hilbert(st_data[0])), np.abs( scipy.signal.hilbert(st_data[1])) data = scipy.odr.Data(x_h, y_h) model = scipy.odr.Model(fit_func) odr = scipy.odr.ODR(data, model, beta0=[1.0]) out = odr.run() h_az_slope = out.beta[0] h_az_error = out.sd_beta[0] h_azimuth = np.arctan2(1.0, h_az_slope) h_az_error = np.degrees( 1.0 / ((1.0**2 + h_az_slope**2) * h_azimuth) * h_az_error) incidence = np.arctan2(1.0, in_slope) in_error = np.degrees(1.0 / ((1.0**2 + in_slope**2) * incidence) * in_error) azimuth = np.degrees(azimuth) incidence = np.degrees(incidence) # Fit to lines using orthoganal distance regression to a linear function if self.group_no == 0: pen = QColor(0, 255, 0) brush = QColor(0, 255, 0, 125) else: pen = QColor(0, 0, 255) brush = QColor(0, 0, 255, 125) if self.plot_type.currentText() == 'Azimuth': p_mot_plot = pg.PlotDataItem() p_mot_plot.setData(x=e, y=n) self.particle_motion_canvas.addItem( pg.InfiniteLine(pos=(0, 0), angle=90 - azimuth, pen=pen)) self.particle_motion_canvas.setLabel( 'bottom', "Channel: {:}".format( self.condensed_stream[0].stats.channel)) self.particle_motion_canvas.setLabel( 'left', "Channel: {:}".format( self.condensed_stream[1].stats.channel)) self.particle_motion_canvas.addItem(p_mot_plot) self.particle_motion_canvas.addItem(pg.TextItem(text='Azimuth = {:.2f}° ± {:.2f}°'.format(azimuth, az_error), color=(255, 0, 0), \ anchor=(0, 0))) self.particle_motion_canvas.setXRange(np.min(e), np.max(e), padding=0) self.particle_motion_canvas.setYRange(np.min(n), np.max(n), padding=0) elif self.plot_type.currentText() == 'Incidence': p_mot_plot = pg.PlotDataItem() p_mot_plot.setData(x=r, y=z) self.particle_motion_canvas.addItem( pg.InfiniteLine(pos=(0, 0), angle=90 - incidence, pen=pen)) self.particle_motion_canvas.setLabel( 'bottom', "Horizontal in Direction of Azimuth") self.particle_motion_canvas.setLabel( 'left', "Channel: {:}".format( self.condensed_stream[2].stats.channel)) self.particle_motion_canvas.addItem(p_mot_plot) self.particle_motion_canvas.addItem(pg.TextItem(text='Incidence = {:.2f}° ± {:.2f}°'.format(incidence, in_error), color=(255, 0, 0), \ anchor=(0, 0))) self.particle_motion_canvas.setXRange(np.min(r), np.max(r), padding=0) self.particle_motion_canvas.setYRange(np.min(z), np.max(z), padding=0) elif self.plot_type.currentText() == 'Jurkevic Azimuth': # fix this bndps = [[0.001, 10], [0.1, 20], [1, 30]] for bb, b in enumerate(bndps): az_list, t_list = jurkevicWindows(z_r, n_r, e_r, st.stats, window_size=win_len, window_overlap=win_frac, bandpass=b) p_mot_plot = pg.ScatterPlotItem() p_mot_plot.setData(x=t_list, y=az_list, pen=pg.intColor(bb), \ brush=pg.intColor(bb), name="Bandpass: {:} - {:} Hz".format(b[0], b[1])) self.particle_motion_canvas.addItem(p_mot_plot) # print("{:} -> Bandpass: {:} - {:} Hz".format(pg.intColor(bb), b[0], b[1])) self.particle_motion_canvas.setLabel('bottom', "Time") self.particle_motion_canvas.setLabel('left', "Azimuth") self.particle_motion_canvas.setXRange(0, np.max(t_list), padding=0) self.particle_motion_canvas.setYRange(0, 180, padding=0) self.particle_motion_canvas.setLimits(xMin=0, xMax=np.max(t_list), yMin=0, yMax=180) elif self.plot_type.currentText() == 'Azimuth Colourmap': bandpass_low = float(self.low_edits.text()) bandpass_high = float(self.high_edits.text()) bins = 15 bin_overlap = 0.5 # this equation is wrong size_of_bin = ((bandpass_high - bandpass_low) - (bins - 1) * bin_overlap) / bins lows = np.linspace(bandpass_low, bandpass_high - size_of_bin, bins) highs = np.linspace(bandpass_low + size_of_bin, bandpass_high, bins) bndps = [] for i in range(len(lows)): bndps.append([lows[i], highs[i]]) total_list = [] for bb, b in enumerate(bndps): az_list, t_list = jurkevicWindows(z_r, n_r, e_r, st.stats, window_size=win_len, window_overlap=1.0, bandpass=b) total_list.append(az_list) img = pg.ImageItem() self.particle_motion_canvas.addItem(img) az_img = np.array(total_list) img.setImage(np.transpose(az_img)) img.scale(t_list[-1]/np.size(az_img, axis=1),\ lows[-1]/np.size(az_img, axis=0)) img.translate(0, bandpass_low) self.hist = pg.HistogramLUTItem() # Link the histogram to the image self.hist.setImageItem(img) if self.added: self.waveform_hist_view.clear() self.waveform_hist_view.addItem(self.hist) self.added = True # Fit the min and max levels of the histogram to the data available self.hist.setLevels(np.min(az_img), np.max(az_img)) # This gradient is roughly comparable to the gradient used by Matplotlib # You can adjust it and then save it using hist.gradient.saveState() self.hist.gradient.restoreState({ 'mode': 'rgb', 'ticks': [(0.5, (0, 182, 188, 255)), (1.0, (246, 111, 0, 255)), (0.0, (75, 0, 113, 255))] }) self.particle_motion_canvas.setLimits(xMin=0, xMax=t_list[-1] + bandpass_low, yMin=bandpass_low, yMax=bandpass_high) self.hist.setHistogramRange(0, 180) # self.particle_motion_canvas.setLookupTable(self.hist) # elif self.plot_type.currentText() == 'Abercrombie 1995': # STEP_DEG = 1 #deg # ba_list = np.arange(0, 360, STEP_DEG) # raw_stream = self.condensed_stream[i].copy() # for ba in ba_list: # raw_stream.rotate('NE->RT', back_azimuth=ba) else: az_window = pol_res['azimuth'] # times are in unix time, casting UTCDatetime to float makes it also unix t_window = pol_res['timestamp'] - float(stime) az_win_error = pol_res['azimuth_error'] p_mot_plot = pg.ScatterPlotItem() p_mot_plot.setData(x=t_window, y=az_window) p_mot_plot_err = pg.ErrorBarItem() p_mot_plot_err.setData(x=t_window, y=az_window, height=az_win_error) azimuth = np.mean(az_window) az_error = np.std(az_window) self.particle_motion_canvas.setLabel('bottom', "Time") self.particle_motion_canvas.setLabel('left', "Azimuth") self.particle_motion_canvas.addItem( pg.InfiniteLine(pos=(0, azimuth), angle=0, pen=pen)) self.particle_motion_canvas.addItem(pg.TextItem(text='Azimuth = {:.2f}° ± {:.2f}°'.format(azimuth, az_error), color=(255, 0, 0), \ anchor=(0, 0))) self.particle_motion_canvas.addItem(p_mot_plot_err) self.particle_motion_canvas.addItem(p_mot_plot) self.particle_motion_canvas.setXRange(0, np.max(t_window), padding=0) self.particle_motion_canvas.setYRange(0, 180, padding=0) # self.particle_motion_canvas.getViewBox().setLimits(xMin=0, xMax=15, # yMin=range_[1][0], yMax=range_[1][1]) self.azimuth = azimuth self.az_error = az_error roi_waveform = pg.PlotDataItem() pts = np.linspace(pt_0/st.stats.sampling_rate + stn.offset - roi[0], \ pt_1/st.stats.sampling_rate + stn.offset - roi[0], num=len(z)) roi_waveform.setData(x=pts, y=bandpassFunc(z, 2, 8, st.stats.delta)) self.waveform_canvas.addItem(roi_waveform) sps = st.stats.sampling_rate dt = 1 / st.stats.sampling_rate length = len(z_r) freq = np.linspace(1 / len_of_region, (sps / 2), length) * sps / length FAS = abs(fft(z_r)) FAS_n = abs(fft(z_n)) fas_data = pg.PlotDataItem() fas_data.setData(x=freq, y=FAS, pen=(255, 0, 0)) fas_noise_data = pg.PlotDataItem() fas_noise_data.setData(x=freq, y=FAS_n, pen=(255, 255, 255)) fas_diff_data = pg.PlotDataItem() fas_diff_data.setData(x=freq, y=np.abs(FAS / FAS_n), pen=(0, 125, 255)) print("Red - Data", "White - Noise", "Blue - Data/Noise") self.waveform_fft_canvas.addItem(fas_data) self.waveform_fft_canvas.addItem(fas_noise_data) self.waveform_fft_canvas.addItem(fas_diff_data)
ax2.yaxis.set_ticks_position('both') ax2.xaxis.set_ticks_position('both') ax2.tick_params(which='both', direction='out') ax2.tick_params(which='both', length=5) ax2.tick_params(which='both', width=1.1) ax2.tick_params(axis='x', which='both', labelsize=0) ax2.set_ylabel('frequency\n(Hz)\n', fontsize=12) ax2.get_yaxis().set_label_coords(-0.08, 0.5) ## Generate polarization plots and add to figure print 'Generating polarization plots for station ' + station particle_motion = polarization_analysis(seismogram_components,\ win_len = 1.0, win_frac = 0.01, frqlow = 1.0, frqhigh = 120.0, method = 'vidale',\ # HARDCODE !!! stime = seismogram_components[0].stats.starttime, etime = seismogram_components[0].stats.endtime) pm_rel_time = np.linspace((obspy.UTCDateTime(particle_motion['timestamp'][0]) - obspy.UTCDateTime(tr_star[tr_stat.index(station)])), \ ((obspy.UTCDateTime(particle_motion['timestamp'][0]) - obspy.UTCDateTime(tr_star[tr_stat.index(station)])) +\ (obspy.UTCDateTime(particle_motion['timestamp'][-1]) - obspy.UTCDateTime(particle_motion['timestamp'][0]))), len(particle_motion['timestamp'])) ax3 = plt.subplot(413) ax3.plot(pm_rel_time, particle_motion['azimuth'], color='k') ax3.set_xlim(3, rel_time[-1] - 1.5) ax3.set_yticks([0, 60, 120, 180]) # HARDCODE !!! ax3.set_ylim([-10, 190]) ax3.set_xlim(3, rel_time[-1] - 1.5) ax3.spines['top'].set_visible(True)
tsreal = tstart tereal = tend # find the real start and end times of all components for i in range(3): tsreal = np.max([tsreal, st3c[i].stats.starttime.timestamp]) tereal = np.min([tereal, st3c[i].stats.endtime.timestamp]) zt = UTCDateTime(atime) ztr = st3c.select(component='Z')[0] ntr = st3c.select(component='N')[0] etr = st3c.select(component='E')[0] if dopolar: win_len = 1.00 win_frac = 0.5 polout = polarization_analysis(st3c, win_len, win_frac, 1., 10., UTCDateTime(tsreal), UTCDateTime(tereal), verbose=True, method="vidale") #plot_polar(st3c, polout) # ---- Calculate polarization based on Roberts et al. pre = 1.0 post = 1.0 azi, inc, coh = baz(ztr.copy(), ntr.copy(), etr.copy(), zt, pre, post) logger.debug('azi {0} inc {1} coh {2}'.format(azi,inc,coh)) logger.debug('seaz {0} esaz {1} '.format(seaz,esaz)) # ---- Calculate polarity of PA fm = '-' if dofm: fm = calc_first_motion(ztr, UTCDateTime(atime), tlag=0.05) logger.debug('FIRST MOTION: {0} '.format(fm)) # css3.0 requires 2 characters if (fm == '-'):
def WavePicking(st,T, SecondP,SecondS,plot): """ P and S Phase picking -input: -st : stream contain the 3 component of the signal -T : float, 5s time of the sliding windows see baillard but could be change trial shoaw goiod result with 5s. -plot: bool, if true plot will be draw -SecondP, float theorical P arrival in second -Seconds,float theorical S arrival in second -output - minF4p: float, coordiantes of the p start in second - minF4s: float, coordiantes of the s start in second calculating using the kitosis derived function and rectilinearity -exemple: minF4p, minF4s = WavePicking3(st_copy,5, 0,10,True) """ # initialisation~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ st = st.copy() trZ = st.select(component = 'Z')[0] sr = int(trZ.stats.sampling_rate) #trH = st.select(component = 'N')[0] trH, CfH = check_best_comp(st, T, sr) df = trZ.stats.sampling_rate #P_Sdelay = (SecondS-SecondP) #DT = max(np.int32(0.5*P_Sdelay*sr), np.int32(0.25*sr)) DT = np.int32(0.25*sr) T_samples = int(T*sr) W_sm = 0.3 # width (s) of the gaussian kernel used for smoothing buf = T_samples + int(2 * W_sm * sr) ## Trim signal ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #if SecondP > 60*5: # a=trZ.stats.starttime # tr_copy.trim(starttime =a + SecondP-60) # trH_copy.trim(starttime =a + SecondP-60) # SecondP =SecondP-60 # if tr_copy.stats.endtime - tr_copy.stats.starttime> 10*60 : # trH_copy.trim(endtime = a + SecondP+60*10) # tr_copy.trim(endtime = a + SecondP+60*10) # st.trim(endtime = a + SecondP+60*10) #elif tr_copy.stats.endtime - tr_copy.stats.starttime> 10*60 : # a=trZ.stats.starttime # trH_copy.trim(endtime = a + SecondP+60*10) # tr_copy.trim(endtime = a + SecondP+60*10) # st.trim(endtime = a + SecondP+60*10) # P phase arrival picking~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Cf = CFkurtosis(trZ, int(T), sr) f2 = F2(Cf) f3 = F3(f2) #f3mean = MeanF3(f3, 0.3, SR=sr) #sliding windows of 0.5 s show good results #f4 = F4(f3mean) f4 = F4(f3) f4prim = F4prim(f4) # S phase arrival picking~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #CfH = CFkurtosis(trH, int(T), sr) f2H = F2(CfH) f3H = F3(f2H) #f3meanN = MeanF3(f3N, 0.3, SR=sr) #sliding windows of 0.5 s show good results #f4N = F4(f3meanN) f4H = F4(f3H) f4primH = F4prim(f4H) #polarisation analysis ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ start1 = trH.stats['starttime'] for tr in st : start = tr.stats['starttime'] if start>start1 : start1 = start pol = polarization_analysis(st,T,0.1,1.5,15,start1,trH.stats['endtime'], verbose=False, method='flinn' , var_noise=0.0) rectilinearity = pol['rectilinearity'] incidence = pol['incidence'] rectilinearity2 = scipy.signal.resample(rectilinearity, len(f4prim),axis=0) incidence2= scipy.signal.resample(incidence, len(f4prim),axis=0) #P S filter cf Ross 2016 sfilter, pfilter = PSswavefilter(rectilinearity2,incidence2) f4prim *= pfilter f4primH *= sfilter sfilter_thrs = sfilter.max()/2. #tr_copyS = trH_copy.copy() #tr_copyP = tr_copy.copy() #tr_copyS = tr_copyS.data * sfilter #tr_copyP = tr_copyP.data * pfilter # P and S wave picking ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ mask = np.arange(buf,len(f4prim)-sr*2) minF4p = buf + np.argmin(f4prim[mask]) # prevent from pointing the end or the beginning of the trace ! #if sfilter[minF4p]>sfilter_thrs : #NOT A p WAVE HD/Working/WavePicking_%s.png'%component,dpi=300) # LminF4p2 = np.argwhere( (f4prim[buf:len(f4prim)-sr*2] < 0.1*f4prim[minF4p]) &\ # (sfilter[buf:len(f4prim)-sr*2] < sfilter_thrs) ) # if len(LminF4p2)>0: # Minp = LminF4p2[f4prim[buf+LminF4p2].argmin()] # Minp1 = 0 # minimum = 0. # for idx in LminF4p2: # if f4prim[buf+idx] < minimum: # Minp1 = idx # minimum = f4prim[idx] # if Minp != Minp1: # print Minp, Minp1 # minF4p = buf + Minp # P picking if isinstance(minF4p,(list, tuple,np.ndarray))==True : minF4p = minF4p[0] start_search = min(minF4p + DT, sfilter.size-2) mask = np.arange(start_search,sfilter.size) min2F4s2 = np.argmin(f4primH[mask]) minF4s2 = start_search + min2F4s2 #if sfilter[minF4s2] < sfilter_thrs : #NOT A S WAVE S limite # LminF4s2 = np.argwhere((f4primH[start_search:] < 0.2*f4primH[minF4s2])) # if len(LminF4s2)>0: # Mins = LminF4s2[f4prim[start_search + LminF4s2].argmin()] # minF4s2 = start_search + Mins #if isinstance(minF4s2, (list, tuple,np.ndarray)) ==True : # minF4s2 = minF4s2[0] # plot ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if plot == True: lw=2 SR = 50. component = trZ.stats.channel #f, (ax0,ax1, ax2, ax3, ax4,ax5,ax6,ax7)=plt.subplots(8, sharex=True) f, axes = plt.subplots(5, sharex=True) (ax0, ax1, ax2, ax3, ax4) = axes x = np.arange(0., st[0].data.size/SR, 1./SR) ax0.plot(x,trH.data) ax0.set_ylabel('Waveform') #---------------------------------------- ax1.plot(x, Cf, label='Sliding kurtosis Z-component', lw=lw) ax1.plot(x,CfH, label='Sliding kurtosis H-component', lw=lw) ax1.set_ylabel('Sliding Kurtosis') #---------------------------------------- ax2.plot(x, f2 , label='First transform Z-component', lw=lw) ax2.plot(x, f2H, label='First transform H-component', lw=lw) ax2.set_ylabel('First Transform') #---------------------------------------- ax3.plot(x,f3, label='Second transform Z-component', lw=lw) ax3.plot(x,f3H, label='Second transform H-component', lw=lw) ax3.set_ylabel('Second Transform') #---------------------------------------- ax4.plot(x, f4prim, label='Third transform Z-component', lw=lw) ax4.plot(x,f4primH, label='Third transform H-component', lw=lw) ax4.set_ylabel('Third Transform') #---------------------------------------- #ax5.plot(x,sfilter) #ax5.axhline(sfilter_thrs, ls='--', color='k') #ax5.axvline(x=minF4p,color= 'C3') #ax5.axvline(x=minF4s2,color= 'C2') #ax5.set_ylabel('$sfilter$') #ax6.plot(x,pfilter) #ax6.axvline(x=minF4p,color= 'C3') #ax6.axvline(x=minF4s2,color= 'C2') #ax6.set_ylabel('$pfilter$') ##ax7.plot(trH_copy, 'k') ##ax7.plot(tr_copyS, 'b') ##ax7.plot(tr_copyP, 'C3') #ax7.axvline(x=minF4p,color= 'C3') #ax7.axvline(x=minF4s2,color= 'C2') for i, ax in enumerate(axes): if i == 0: ax.axvline(x=np.float32(minF4p)/SR , color= 'C3', lw=lw, label='Picked P wave') ax.axvline(x=np.float32(minF4s2)/SR, color= 'C2', lw=lw, label='Picked S wave') else: ax.axvline(x=np.float32(minF4p)/SR , color= 'C3', ls='--', lw=0.75) ax.axvline(x=np.float32(minF4s2)/SR ,color= 'C2', ls='--', lw=0.75) ax.legend(loc='lower right', fancybox=True, framealpha=1.) if i == len(axes)-1: ax.set_xlabel('Time (s)') #ax.set_xlim(x.min(), x.max()) ax.set_xlim(x.min(), 40.) ax0.set_title('%s.%s (sliding window\'s duration=%.1fs)' %(trZ.stats.station, trZ.stats.channel, T)) return minF4p/df, minF4s2/df