def test_xcorrPickCorrection(self): """ Test cross correlation pick correction on a set of two small local earthquakes. """ st1 = read(os.path.join(self.path, 'BW.UH1._.EHZ.D.2010.147.a.slist.gz')) st2 = read(os.path.join(self.path, 'BW.UH1._.EHZ.D.2010.147.b.slist.gz')) tr1 = st1.select(component="Z")[0] tr2 = st2.select(component="Z")[0] t1 = UTCDateTime("2010-05-27T16:24:33.315000Z") t2 = UTCDateTime("2010-05-27T16:27:30.585000Z") dt, coeff = xcorrPickCorrection(t1, tr1, t2, tr2, 0.05, 0.2, 0.1) self.assertAlmostEqual(dt, -0.014459080288833711) self.assertAlmostEqual(coeff, 0.91542878457939791) dt, coeff = xcorrPickCorrection(t2, tr2, t1, tr1, 0.05, 0.2, 0.1) self.assertAlmostEqual(dt, 0.014459080288833711) self.assertAlmostEqual(coeff, 0.91542878457939791) dt, coeff = xcorrPickCorrection( t1, tr1, t2, tr2, 0.05, 0.2, 0.1, filter="bandpass", filter_options={'freqmin': 1, 'freqmax': 10}) self.assertAlmostEqual(dt, -0.013025086360067755) self.assertAlmostEqual(coeff, 0.98279277273758803)
def test_xcorrPickCorrection(self): """ Test cross correlation pick correction on a set of two small local earthquakes. """ st1 = read( os.path.join(self.path, 'BW.UH1._.EHZ.D.2010.147.a.slist.gz')) st2 = read( os.path.join(self.path, 'BW.UH1._.EHZ.D.2010.147.b.slist.gz')) tr1 = st1.select(component="Z")[0] tr2 = st2.select(component="Z")[0] t1 = UTCDateTime("2010-05-27T16:24:33.315000Z") t2 = UTCDateTime("2010-05-27T16:27:30.585000Z") dt, coeff = xcorrPickCorrection(t1, tr1, t2, tr2, 0.05, 0.2, 0.1) self.assertAlmostEqual(dt, -0.014459080288833711) self.assertAlmostEqual(coeff, 0.91542878457939791) dt, coeff = xcorrPickCorrection(t2, tr2, t1, tr1, 0.05, 0.2, 0.1) self.assertAlmostEqual(dt, 0.014459080288833711) self.assertAlmostEqual(coeff, 0.91542878457939791) dt, coeff = xcorrPickCorrection(t1, tr1, t2, tr2, 0.05, 0.2, 0.1, filter="bandpass", filter_options={ 'freqmin': 1, 'freqmax': 10 }) self.assertAlmostEqual(dt, -0.013025086360067755) self.assertAlmostEqual(coeff, 0.98279277273758803)
def align_trace(std_trace, traces): t1 = 3 t_std = std_trace.stats.starttime + t1 # std_trace.plot() print "t_std", t_std for trace in traces: # trace.plot() starttime = trace.stats.starttime + t1 print 'starttime', starttime dt, coeff = xcorrPickCorrection( starttime, trace, t_std, std_trace, 0.0, 15.0, t1, plot=True)
def subsample_xcorr_shift(d, s): """ Calculate the correlation time shift around the maximum amplitude of the synthetic trace with subsample accuracy. """ # Estimate shift and use it as a guideline for the subsample accuracy # shift. time_shift = _xcorr_shift(d.data, s.data) * d.stats.delta # Align on the maximum amplitude of the synthetics. pick_time = s.stats.starttime + s.data.argmax() * s.stats.delta # Will raise a warning if the trace ids don't match which we don't care # about here. with warnings.catch_warnings(): warnings.simplefilter("ignore") return xcorrPickCorrection( pick_time, s, pick_time, d, 20.0 * time_shift, 20.0 * time_shift, 10.0 * time_shift)[0]
def subsample_xcorr_shift(d, s): """ Calculate the correlation time shift around the maximum amplitude of the synthetic trace with subsample accuracy. """ # Estimate shift and use it as a guideline for the subsample accuracy # shift. time_shift = _xcorr_shift(d.data, s.data) * d.stats.delta # Align on the maximum amplitude of the synthetics. pick_time = s.stats.starttime + s.data.argmax() * s.stats.delta # Will raise a warning if the trace ids don't match which we don't care # about here. with warnings.catch_warnings(): warnings.simplefilter("ignore") return xcorrPickCorrection(pick_time, s, pick_time, d, 20.0 * time_shift, 20.0 * time_shift, 10.0 * time_shift)[0]
# read example data of two small earthquakes st1 = read("http://examples.obspy.org/BW.UH1..EHZ.D.2010.147.a.slist.gz") st2 = read("http://examples.obspy.org/BW.UH1..EHZ.D.2010.147.b.slist.gz") # select the single traces to use in correlation. # to avoid artifacts from preprocessing there should be some data left and # right of the short time window actually used in the correlation. tr1 = st1.select(component="Z")[0] tr2 = st2.select(component="Z")[0] # these are the original pick times set during routine analysis t1 = UTCDateTime("2010-05-27T16:24:33.315000Z") t2 = UTCDateTime("2010-05-27T16:27:30.585000Z") # estimate the time correction for pick 2 without any preprocessing and open # a plot window to visually validate the results dt, coeff = xcorrPickCorrection(t1, tr1, t2, tr2, 0.05, 0.2, 0.1, plot=True) print "No preprocessing:" print " Time correction for pick 2: %.6f" % dt print " Correlation coefficient: %.2f" % coeff # estimate the time correction with bandpass prefiltering dt, coeff = xcorrPickCorrection(t1, tr1, t2, tr2, 0.05, 0.2, 0.1, plot=True, filter="bandpass", filter_options={ 'freqmin': 1,
def write_correlations(event_list, wavbase, extract_len, pre_pick, shift_len,\ lowcut=1.0, highcut=10.0, max_sep=4, min_link=8, \ coh_thresh=0.0): """ Function to write a dt.cc file for hypoDD input - takes an input list of events and computes pick refienements by correlation. Note that this is **NOT** fast. :type event_list: List of tuple :param event_list: List of tuples of event_id (int) and sfile (String) :type wavbase: string :param wavbase: Path to the seisan wave directory that the wavefiles in the S-files are stored :type extract_len: float :param extract_len: Length in seconds to extract around the pick :type pre_pick: float :param pre_pick: Time before the pick to start the correclation window :type shift_len: float :param shift_len: Time to allow pick to vary :type lowcut: float :param lowcut: Lowcut in Hz - default=1.0 :type highcut: float :param highcut: Highcut in Hz - deafult=10.0 :type max_sep: float :param max_sep: Maximum seperation between event pairs in km :type min_link: int :param min_link: Minimum links for an event to be paired """ from obspy.signal.cross_correlation import xcorrPickCorrection import matplotlib.pyplot as plt from obspy import read from eqcorrscan.utils.mag_conv import dist_calc import glob corr_list=[] f=open('dt.cc','w') for i in xrange(len(event_list)): master_sfile=event_list[i][1] master_event_id=event_list[i][0] master_picks=Sfile_util.readpicks(master_sfile) master_ori_time=Sfile_util.readheader(master_sfile).time master_location=(Sfile_util.readheader(master_sfile).latitude,\ Sfile_util.readheader(master_sfile).longitude,\ Sfile_util.readheader(master_sfile).depth) master_wavefiles=Sfile_util.readwavename(master_sfile) masterpath=glob.glob(wavbase+os.sep+'????'+os.sep+'??'+os.sep+master_wavefiles[0]) if masterpath: masterstream=read(masterpath[0]) if len(master_wavefiles)>1: for wavefile in master_wavefiles: wavepath=glob.glob(wavbase+os.sep+'*'+os.sep+'*'+os.sep+wavefile) if wavepath: masterstream+=read(wavepath[0]) else: raise IOError("Couldn't find wavefile") for j in xrange(i+1,len(event_list)): # Use this tactic to only output unique event pairings slave_sfile=event_list[j][1] slave_event_id=event_list[j][0] slave_wavefiles=Sfile_util.readwavename(slave_sfile) try: slavestream=read(wavbase+'/*/*/'+slave_wavefiles[0]) except: raise IOError('No wavefile found: '+slave_wavefiles[0]+' '+slave_sfile) if len(slave_wavefiles)>1: for wavefile in slave_wavefiles: slavestream+=read(wavbase+'/*/*/'+wavefile) # Write out the header line event_text='#'+str(master_event_id).rjust(10)+\ str(slave_event_id).rjust(10)+' 0.0 \n' slave_picks=Sfile_util.readpicks(slave_sfile) slave_ori_time=Sfile_util.readheader(slave_sfile).time slave_location=(Sfile_util.readheader(slave_sfile).latitude,\ Sfile_util.readheader(slave_sfile).longitude,\ Sfile_util.readheader(slave_sfile).depth) if dist_calc(master_location, slave_location) > max_sep: break links=0 phases=0 for pick in master_picks: if pick.phase not in ['P','S']: continue # Only use P and S picks, not amplitude or 'other' # Find station, phase pairs slave_matches=[p for p in slave_picks if p.station==pick.station\ and p.phase==pick.phase] if masterstream.select(station=pick.station, \ channel='*'+pick.channel[-1]): mastertr=masterstream.select(station=pick.station, \ channel='*'+pick.channel[-1])[0] else: print 'No waveform data for '+pick.station+'.'+pick.channel print pick.station+'.'+pick.channel+' '+slave_sfile+' '+master_sfile break # Loop through the matches for slave_pick in slave_matches: if slavestream.select(station=slave_pick.station,\ channel='*'+slave_pick.channel[-1]): slavetr=slavestream.select(station=slave_pick.station,\ channel='*'+slave_pick.channel[-1])[0] else: print 'No slave data for '+slave_pick.station+'.'+\ slave_pick.channel print pick.station+'.'+pick.channel+' '+slave_sfile+' '+master_sfile break # Correct the picks try: correction, cc = xcorrPickCorrection(pick.time, mastertr,\ slave_pick.time,\ slavetr,pre_pick,\ extract_len-pre_pick, shift_len,\ filter="bandpass",\ filter_options={'freqmin':lowcut, 'freqmax':highcut},plot=False) # Get the differntial travel time using the corrected time. dt=(pick.time-master_ori_time)-\ (slave_pick.time+correction-slave_ori_time) links+=1 if cc*cc >= coh_thresh: phases+=1 #added by Caro event_text+=pick.station.ljust(4)+\ _cc_round(correction,3).rjust(11)+\ _cc_round(cc,3).rjust(8)+\ ' '+pick.phase+'\n' # links+=1 corr_list.append(cc*cc) except: continue if links >= min_link and phases > 0: f.write(event_text) plt.hist(corr_list, 150) plt.show() # f.write('\n') f.close() f2.close() return
from __future__ import print_function from obspy.core import read, UTCDateTime from obspy.signal.cross_correlation import xcorrPickCorrection # read example data of two small earthquakes st1 = read("http://examples.obspy.org/BW.UH1..EHZ.D.2010.147.a.slist.gz") st2 = read("http://examples.obspy.org/BW.UH1..EHZ.D.2010.147.b.slist.gz") # select the single traces to use in correlation. # to avoid artifacts from preprocessing there should be some data left and # right of the short time window actually used in the correlation. tr1 = st1.select(component="Z")[0] tr2 = st2.select(component="Z")[0] # these are the original pick times set during routine analysis t1 = UTCDateTime("2010-05-27T16:24:33.315000Z") t2 = UTCDateTime("2010-05-27T16:27:30.585000Z") # estimate the time correction for pick 2 without any preprocessing and open # a plot window to visually validate the results dt, coeff = xcorrPickCorrection(t1, tr1, t2, tr2, 0.05, 0.2, 0.1, plot=True) print("No preprocessing:") print(" Time correction for pick 2: %.6f" % dt) print(" Correlation coefficient: %.2f" % coeff) # estimate the time correction with bandpass prefiltering dt, coeff = xcorrPickCorrection(t1, tr1, t2, tr2, 0.05, 0.2, 0.1, plot=True, filter="bandpass", filter_options={'freqmin': 1, 'freqmax': 10}) print("Bandpass prefiltering:") print(" Time correction for pick 2: %.6f" % dt) print(" Correlation coefficient: %.2f" % coeff)