def seism_picker(picktype,args,stream): """ A simple cover function for th eobspy picking modules :type picktype: String :param picktype: Eother Baer or AR for Auto-regressive :type args: Class :param args: List of appropriate arguments for the chosen pick type - defined in picker_par.py :type Stream: obspy.Stream :return: p_pick, s_pick """ import sys if picktype == 'Baer': from obspy.signal.trigger import pkBaer p_pick=[] phase_info=[] station_info=[] for tr in stream: trp_pick, trphase_info = pkBaer(tr.data, tr.stats.sampling_rate, args.tdownmax, args.tupevent, args.thr1, args.thr2, args.preset_len, args.p_dur) # 20, 60, 7.0, 12.0, 100, 100) trp_pick=trp_pick/tr.stats.sampling_rate p_pick+=[trp_pick] phase_info+=[trphase_info] station_info+=[tr.stats.station+'.'+tr.stats.channel] return p_pick, phase_info, station_info elif picktype == 'AR': if len(stream) != 3: print 'Stream must be three channels from the same station' sys.exit() from obspy.signal.trigger import arPick tr1=stream.select(channel='*Z')[0] try: tr2=stream.select(channel='*N')[0] except: tr2=stream.select(channel='*1')[0] try: tr3=stream.select(channel='*E')[0] except: tr3=stream.select(channel='*2')[0] df=tr1.stats.sampling_rate p_pick, s_pick = arPick(tr1.data, tr2.data, tr3.data, df, args.f1, args.f2, args.lta_p, args.sta_p, args.lta_s, args.sta_s, args.m_p, args.m_s, args.l_p, args.l_s, args.s_pick) #1.0, 20.0, 1.0, 0.1, 4.0, 1.0, 2, 8, 0.1, 0.2) return p_pick, s_pick
def ProcessLoopP(filepath): '''The file processing loop associated with P wave tomography: Just deal with the BHZ files to save time''' sacfiles = glob.glob('*.BHZ') #Check to see if there is more than one location for a given station stationnames = [] for sacfile in sorted(sacfiles): sacfilenameparts = sacfile.split('.') stationname = sacfilenameparts[2] if stationname not in stationnames: stationnames.append(stationname) trace = read(sacfile) evlat = trace[0].stats.sac.evla evlon = trace[0].stats.sac.evlo evdep = trace[0].stats.sac.evdp stlat = trace[0].stats.sac.stla stlon = trace[0].stats.sac.stlo dist = locations2degrees(evlat,evlon,stlat,stlon) #find distance from the quake to the station arcs = IRISclient.distaz(stalat=stlat,stalon=stlon,evtlat=evlat,evtlon=evlon) az = arcs['backazimuth'] baz = arcs['azimuth'] #If we're running this code twice in a row, need to correct the evdep accordingly. The evdep that comes from obspy will be in km, but needs #to be in the SAC header in meters. If the depth is already in meters in the SACfile, then it will almost certainly be >1000. This if statement check for #this, and converts to km if necessary if evdep > 1e3: evdep = evdep/1000.0 traveltimes = getTravelTimes(dist,evdep, model='iasp91') P = 0 S = 0 for element in traveltimes: phaseinfo = element['phase_name'] if phaseinfo == 'P': Ptime = element['time'] P = 1 if phaseinfo == 'S': Stime = element['time'] S = 1 if (P==1 and S==1): break try: P = Ptime except: Ptime = 0 try: S = Stime except: Stime = 0 #Set the P and S times trace[0].stats.sac.az = float(az) trace[0].stats.sac.baz = float(baz) trace[0].stats.sac.o = 0.0 #add origin time if Ptime > 0: trace[0].stats.sac.t1 = Ptime if Stime > 0: trace[0].stats.sac.t2 = Stime trace[0].stats.sac.evdp = evdep*1000 #dbpick wants depth to be in meters #other operations trace[0].detrend('demean') #THE CROSS CORRELATION CODE ASSUMES A SAMPLING RATE OF 0.05 (20 SAMPLES/SECOND). IT WILL NOT WORK #OTHERWISE!!! trace[0].resample(20) if results.autop: tracestreamP = trace.copy() df = tracestreamP[0].stats.sampling_rate filter1 = 0.02 filter2 = 0.1 tracestreamP.filter("bandpass",freqmin=filter1,freqmax=filter2,corners=2) tracestreamP.taper(max_percentage=0.05, type='cosine') p_pick, phase_info = pkBaer(tracestreamP[0].data,df,10,2,2,10,20,6) #output from this is in samples. autoPtime = p_pick/df #Append the autopicker's time to the if abs(Ptime-autoPtime) < 20: print 'Autopick accepted!' trace[0].stats.sac.t3 = autoPtime #Important - must write to the SAC file! trace.write(sacfile,format='SAC') print 'Appended arrivals to %s' %sacfile else: print 'Found multiple instruments at station %s. Removing all but 1' %(stationname) os.system('rm %s' %sacfile) #create antelope database for P arrivals os.system('sac2db *.BHZ Z')
def AutoPick(pickdir='Trigs',outputFormat='HYP',outdir='PickTimes',picker='pkBaer',goodPick='goodpicking', startnum='StartHere.txt',filelist=None): StaKey=pd.read_csv('StationKey.csv') if not os.path.isdir(outdir): os.makedirs(outdir) if not os.path.isdir(goodPick): os.makedirs(goodPick) latmin,latmax,lonmin,lonmax=_getLimits(StaKey) dA,A=_getdA(6371) #calculates symbolically the partial derivatives of the operator for location inversion count=0 if isinstance(filelist,list): files=filelist else: files=glob.glob(os.path.join(pickdir,'*')) try: #Look for startnum txt to see where to begin start=int(np.loadtxt(startnum).tolist()+int(np.random.rand()*10)) except: print 'No progress file, begining at 0' for fil in range(start,len(files)): ST=obspy.core.read(files[fil]) filename=os.path.basename(files[fil]).replace('msd','pha') with open(os.path.join(outdir,filename),'wb') as pik: Stations=StaKey.STATION STR=[0]*len(Stations) pks=[1]*len(Stations) cou=0 Key=StaKey.copy() Key['Ppick']=0.000000000 Key['Spick']=0.000000000 Key['Trace']=object for sta in Key.iterrows(): st=ST.copy() st=st.select(station=sta[1].STATION) if len(st)==0: #If station not found skip iteration continue sr=st[0].stats.sampling_rate STR[cou]=st.copy() cou+=1 for tr in range(len(STR)): if picker=='arPick': Z,N,E=STR[tr].select(channel='*Z').copy(), STR[tr].select(channel='*N').copy(),STR[tr].select(channel='*E').copy() p_pick, s_pick = arPick(Z[0].data, N[0].data,E[0].data, Z[0].stats.sampling_rate,1.0, 15.0, 1.0, 0.1, 4.0, 1.0, 2, 8, 0.1, 0.2) elif picker=='pkBaer': zst=STR[tr].select(channel='*Z') p_pick, phase_info = pkBaer(zst[0].data, sr,20, 60, 1.2, 10.0, 100, 100) if p_pick==1 or p_pick<0: #if baer/arPicker pick failes resort to basic recursive STA/LTA picks cft=recSTALTA(STR[tr].select(channel='*Z')[0].data, int(1 * sr), int(10 * sr)) p_pick=cft.argmax() pks[tr]=p_pick Key['Ppick'][int(tr)]=STR[tr][0].stats.starttime.timestamp+p_pick/float(sr) Key['Trace'][int(tr)]=STR[tr][0] #print (p_pick) for sta in Key.drop_duplicates(cols='Ppick').iterrows(): if outputFormat=='NNL': if picker=='arPick': line1,line2=_makeArPickNLLLine(sta[1].Ppick,s_pick,STR[tr]) pik.write(line1) pik.write(line2) if picker=='pkBaer': line1=_makePkBaerNLLLine(sta[1].Ppick,sta[1].Trace.stats.sampling_rate,sta[1].Trace) pik.write(line1) if outputFormat=='HYP': if picker=='pkBaer': try: line=_makePkBaerHYPLine(sta[1].Ppick,sta[1].Trace.stats.sampling_rate,sta[1].Trace) except: break pik.write(line) m=invertForLocation(Key,dA,A) if outputFormat=='NNL': pass #write this in later if outputFormat=='HYP' and m[0]>-90 and m[0]<90 and m[1]>-180 and m[1]<180: endline=writeEndLine(m,Key) #print np.min(np.min(Key.Ppick.values)) pik.write(endline) pik.write('\n') #Key=_genSynthetics(Key,A) if m[0] < latmin or m[0] > latmax or m[1] < lonmin or m[1] > lonmax: #If rough location is in station peremeter make picks and copy file os.remove(os.path.join(outdir,filename)) else: shutil.copy(files[fil],os.path.join(goodPick,os.path.basename(files[fil]))) print filename count+=1 if count%10==0: _writeProgressFile(count)