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
def write_catalogue(event_list, max_sep=1, min_link=8): """ Function to write the dt.ct file needed by hypoDD - takes input event list from write_event as a list of tuples of event id and sfile. It will read the pick information from the seisan formated s-file using the Sfile_util utilities. :type event_list: List of tuple :param event_list: List of tuples of event_id (int) and sfile (String) :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 :returns: List stations """ from eqcorrscan.utils.mag_calc import dist_conv f=open('dt.ct','w') fphase=open('phase.dat','w') stations=[] evcount=0 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 # print 'Master origin time: '+str(master_ori_time) master_location=(Sfile_util.readheader(master_sfile).latitude,\ Sfile_util.readheader(master_sfile).longitude,\ Sfile_util.readheader(master_sfile).depth) header='# '+str(master_ori_time.year) fphase.write(header+'\n') for pick in master_picks: fphase.write(pick.station+' '+_cc_round(pick.time-master_ori_time,3)+\ ' '+'\n') 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] # Write out the header line event_text='#'+str(master_event_id).rjust(10)+\ str(slave_event_id).rjust(10)+'\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 # Count the number of linkages 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] # Loop through the matches for slave_pick in slave_matches: links+=1 event_text+=pick.station.ljust(4)+\ _cc_round(pick.time-master_ori_time,3).rjust(11)+\ _cc_round(slave_pick.time-slave_ori_time,3).rjust(8)+\ _av_weight(pick.weight, slave_pick.weight).rjust(7)+' '+\ pick.phase+'\n' stations.append(pick.station) if links >= min_link: f.write(event_text) evcount+=1 print 'You have '+str(evcount)+' links' # f.write('\n') f.close() fphase.close() return list(set(stations))