def get_Z(select_event=0): from obspy.clients.fdsn import Client import matplotlib.pyplot as plt from obspy import read_events, read from obspy import read_inventory from obspy import Stream, Trace from obspy import UTCDateTime import os client = Client('SCEDC') os.environ['PATH'] += os.pathsep + '/usr/local/bin' os.chdir('/Users/vidale/Documents/PyCode/LAB/Spare') # select_event = 15 chan_type = 'EHZ,HHZ,HNZ,HLZ,BHZ' # e.g., BHZ network_sel = 'CI,CE,NP' # CE has four traces, but won't deconvolve #network_sel = 'CI,NP' min_lat = 33.75 max_lat = 34.2 min_lon = -118.5 max_lon = -117.75 start_buff = 50 end_buff = 300 st = Stream() if select_event > 15: fname_inv = 'LAB.QUAKEML2' LAB = read_events(fname_inv, format='QUAKEML') if select_event == 16: t = LAB[1].origins[0].time elif select_event == 17: t = LAB[5].origins[0].time elif select_event == 18: t = LAB[14].origins[0].time elif select_event == 19: t = LAB[13].origins[0].time else: fname_inv = 'LAB.QUAKEML' LAB = read_events(fname_inv, format='QUAKEML') t = LAB[select_event].origins[0].time #print('event:',LAB) #plt.style.use('ggplot') #plt.rcParams['figure.figsize'] = 12, 8 #LAB.plot(projection = 'local', resolution = 'h') #%% Make inventory of all stations in box recording this channel print(str(t)) s_t = t - start_buff e_t = t + end_buff inventory = client.get_stations(starttime=s_t, endtime=e_t, channel=chan_type, level='response', network=network_sel, minlatitude=min_lat, maxlatitude=max_lat, minlongitude=min_lon, maxlongitude=max_lon) #print(inventory) print('inventory has ' + str(len(inventory)) + ' networks recording data') #for network in inventory: # sta_cnt = 0 # for station in network: # sta_cnt += sta_cnt # print('Network ' + str(network) + ' has ' + str(sta_cnt) + ' stations to try') #inventory.plot(projection = 'local', resolution = 'h') # not working #%% Check inventory of stations for traces at time of event cnt_try = 0 cnt_got = 0 for network in inventory: for station in network: if cnt_try % 20 == 0: print('Try ' + str(cnt_try) + ' got ' + str(cnt_got) + ' sgrams ' + str(len(st))) cnt_try += +1 try: st += client.get_waveforms(network.code, station.code, location='*', channel=chan_type, starttime=s_t, endtime=e_t, attach_response=True) cnt_got += 1 except: pass print( str(cnt_try) + ' stations examined, ' + str(cnt_got) + ' have data, ' + str(len(st)) + ' traces extracted ') fname = 'event' + str(select_event) + '/event' + str( select_event) + 'Z_all.mseed' st.write(fname, format='MSEED') ''' st=read(fname) ''' for tr in st: print('Station ' + tr.stats.station + ' channel ' + tr.stats.channel) tr = Trace() hnz_chosen = 0 ehz_chosen = 0 hhz_chosen = 0 hlz_chosen = 0 bhz_chosen = 0 for tr in st: if tr.stats.channel == 'HNZ': hnz_chosen += 1 if tr.stats.channel == 'EHZ': ehz_chosen += 1 if tr.stats.channel == 'HHZ': hhz_chosen += 1 if tr.stats.channel == 'HLZ': hlz_chosen += 1 if tr.stats.channel == 'BHZ': bhz_chosen += 1 print('Total channels ' + str(len(st)) + ' - HNZ, EHZ, HHZ, HLZ, BHZ have ' + str(hnz_chosen) + ' ' + str(ehz_chosen) + ' ' + str(hhz_chosen) + ' ' + str(hlz_chosen) + ' ' + str(bhz_chosen)) for tr in st: if (tr.stats.network != 'CE') and (tr.stats.station != 'BVH') and ( tr.stats.station != 'LAX'): # if tr.stats.network != 'CE' and not (tr.stats.station == 'BVH' and tr.stats.channel == 'EHZ'): print('Station ' + tr.stats.station + ' channel ' + tr.stats.channel) tr.remove_response(water_level=40, inventory=inventory, output='ACC') fname = 'event' + str(select_event) + '/event' + str( select_event) + 'Z_decon.mseed' st.write(fname, format='MSEED') ''' st=read('event14Z_decon.mseed') ''' tr2 = Trace() st_chosen = Stream() hhz_chosen = 0 ehz_chosen = 0 hnz_chosen = 0 hlz_chosen = 0 bhz_chosen = 0 for tr in st: if tr.stats.channel == 'HNZ': st_chosen += tr hnz_chosen += 1 elif tr.stats.channel == 'EHZ': # write EHZ if present and BHZ is not present skip = 0 for tr2 in st: if tr2.stats.channel == 'HNZ' and tr2.stats.station == tr.stats.station: skip = 1 if skip == 0: st_chosen += tr ehz_chosen += 1 elif tr.stats.channel == 'HHZ': skip = 0 for tr2 in st: if tr2.stats.channel == 'HNZ' and tr2.stats.station == tr.stats.station: skip = 1 if tr2.stats.channel == 'EHZ' and tr2.stats.station == tr.stats.station: skip = 1 if skip == 0: st_chosen += tr hhz_chosen += 1 elif tr.stats.channel == 'HLZ': skip = 0 for tr2 in st: if tr2.stats.channel == 'HNZ' and tr2.stats.station == tr.stats.station: skip = 1 if tr2.stats.channel == 'EHZ' and tr2.stats.station == tr.stats.station: skip = 1 if tr2.stats.channel == 'HHZ' and tr2.stats.station == tr.stats.station: skip = 1 if skip == 0: st_chosen += tr hlz_chosen += 1 elif tr.stats.channel == 'BHZ': skip = 0 for tr2 in st: if tr2.stats.channel == 'HNZ' and tr2.stats.station == tr.stats.station: skip = 1 if tr2.stats.channel == 'EHZ' and tr2.stats.station == tr.stats.station: skip = 1 if tr2.stats.channel == 'HHZ' and tr2.stats.station == tr.stats.station: skip = 1 if tr2.stats.channel == 'HLZ' and tr2.stats.station == tr.stats.station: skip = 1 if skip == 0: st_chosen += tr bhz_chosen += 1 for tr in st_chosen: print(tr.stats.station + ' ' + tr.stats.channel) print('Chosen - HNZ, EHZ, HHZ, HLZ, BHZ have ' + str(hnz_chosen) + ' ' + str(ehz_chosen) + ' ' + str(hhz_chosen) + ' ' + str(hlz_chosen) + ' ' + str(bhz_chosen)) print(str(len(st_chosen)) + ' traces in dataset') fname = 'event' + str(select_event) + '/event' + str( select_event) + 'Z_chosen.mseed' st_chosen.write(fname, format='MSEED')
def xcorr2(tr1, tr2, sta1_inv=None, sta2_inv=None, instrument_response_output='vel', water_level=50., window_seconds=3600, window_overlap=0.1, window_buffer_length=0, interval_seconds=86400, taper_length=0.05, resample_rate=None, flo=None, fhi=None, clip_to_2std=False, whitening=False, whitening_window_frequency=0, one_bit_normalize=False, envelope_normalize=False, verbose=1, logger=None): # Length of window_buffer in seconds window_buffer_seconds = window_buffer_length * window_seconds adjusted_taper_length = taper_length if (window_buffer_seconds): # adjust taper length adjusted_taper_length = taper_length / (1. + window_buffer_length * 2.) # end if sr1 = tr1.stats.sampling_rate sr2 = tr2.stats.sampling_rate sr1_orig = sr1 sr2_orig = sr2 tr1_d_all = tr1.data # refstn tr2_d_all = tr2.data lentr1_all = tr1_d_all.shape[0] lentr2_all = tr2_d_all.shape[0] window_samples_1 = (window_seconds + 2 * window_buffer_seconds) * sr1 window_samples_2 = (window_seconds + 2 * window_buffer_seconds) * sr2 interval_samples_1 = interval_seconds * sr1 interval_samples_2 = interval_seconds * sr2 sr = 0 resll = [] # set day-aligned start-indices maxStartTime = max(tr1.stats.starttime, tr2.stats.starttime) dayAlignedStartTime = UTCDateTime(year=maxStartTime.year, month=maxStartTime.month, day=maxStartTime.day) itr1s = (dayAlignedStartTime - tr1.stats.starttime) * sr1 itr2s = (dayAlignedStartTime - tr2.stats.starttime) * sr2 if (resample_rate): sr1 = resample_rate sr2 = resample_rate # end if sr = max(sr1, sr2) xcorlen = int(2 * window_seconds * sr - 1) fftlen = 2**(int(np.log2(xcorlen)) + 1) intervalCount = 0 windowsPerInterval = [ ] # Stores the number of windows processed per interval intervalStartSeconds = [] intervalEndSeconds = [] while itr1s < lentr1_all and itr2s < lentr2_all: itr1e = min(lentr1_all, itr1s + interval_samples_1) itr2e = min(lentr2_all, itr2s + interval_samples_2) while ((itr1s < 0) or (itr2s < 0)): itr1s += (window_samples_1 - 2*window_buffer_seconds*sr1_orig) - \ (window_samples_1 - 2*window_buffer_seconds*sr1_orig) * window_overlap itr2s += (window_samples_2 - 2*window_buffer_seconds*sr2_orig) - \ (window_samples_2 - 2*window_buffer_seconds*sr2_orig) * window_overlap # end while if (np.fabs(itr1e - itr1s) < sr1_orig or np.fabs(itr2e - itr2s) < sr2_orig): itr1s = itr1e itr2s = itr2e continue # end if if (tr1.stats.starttime + itr1s / sr1_orig != tr2.stats.starttime + itr2s / sr2_orig): if (logger): logger.warning('Detected misaligned traces..') windowCount = 0 wtr1s = int(itr1s) wtr2s = int(itr2s) resl = [] while wtr1s < itr1e and wtr2s < itr2e: wtr1e = int(min(itr1e, wtr1s + window_samples_1)) wtr2e = int(min(itr2e, wtr2s + window_samples_2)) # Discard small windows if ((wtr1e - wtr1s < window_samples_1) or (wtr2e - wtr2s < window_samples_2) or (wtr1e - wtr1s < sr1_orig) or (wtr2e - wtr2s < sr2_orig)): wtr1s = int(np.ceil(itr1e)) wtr2s = int(np.ceil(itr2e)) continue # end if # Discard windows with masked regions, i.e. with gaps or windows that are all zeros if (not (np.ma.is_masked(tr1_d_all[wtr1s:wtr1e]) or np.ma.is_masked(tr2_d_all[wtr2s:wtr2e]) or np.sum(tr1_d_all[wtr1s:wtr1e]) == 0 or np.sum(tr2_d_all[wtr2s:wtr2e]) == 0)): #logger.info('%s, %s' % (tr1.stats.starttime + wtr1s / 200., tr1.stats.starttime + wtr1e / sr1_orig)) #logger.info('%s, %s' % (tr2.stats.starttime + wtr2s / 200., tr2.stats.starttime + wtr2e / sr2_orig)) tr1_d = np.array(tr1_d_all[wtr1s:wtr1e], dtype=np.float32) tr2_d = np.array(tr2_d_all[wtr2s:wtr2e], dtype=np.float32) # STEP 1: detrend tr1_d = signal.detrend(tr1_d) tr2_d = signal.detrend(tr2_d) # STEP 2: demean tr1_d -= np.mean(tr1_d) tr2_d -= np.mean(tr2_d) # STEP 3: remove response if (sta1_inv): resp_tr1 = Trace( data=tr1_d, header=Stats( header={ 'sampling_rate': sr1_orig, 'npts': len(tr1_d), 'network': tr1.stats.network, 'station': tr1.stats.station, 'location': tr1.stats.location, 'channel': tr1.stats.channel, 'starttime': tr1.stats.starttime + float(wtr1s) / sr1_orig, 'endtime': tr1.stats.starttime + float(wtr1e) / sr1_orig })) try: resp_tr1.remove_response( inventory=sta1_inv, output=instrument_response_output.upper(), water_level=water_level) except Exception as e: print(e) # end try tr1_d = resp_tr1.data # end if # remove response if (sta2_inv): resp_tr2 = Trace( data=tr2_d, header=Stats( header={ 'sampling_rate': sr2_orig, 'npts': len(tr2_d), 'network': tr2.stats.network, 'station': tr2.stats.station, 'location': tr2.stats.location, 'channel': tr2.stats.channel, 'starttime': tr2.stats.starttime + float(wtr2s) / sr2_orig, 'endtime': tr2.stats.starttime + float(wtr2e) / sr2_orig })) try: resp_tr2.remove_response( inventory=sta2_inv, output=instrument_response_output.upper(), water_level=water_level) except Exception as e: print(e) # end try tr2_d = resp_tr2.data # end if # STEPS 4, 5: resample after lowpass @ resample_rate/2 Hz if (resample_rate): tr1_d = lowpass(tr1_d, resample_rate / 2., sr1_orig, corners=2, zerophase=True) tr2_d = lowpass(tr2_d, resample_rate / 2., sr2_orig, corners=2, zerophase=True) tr1_d = Trace( data=tr1_d, header=Stats(header={ 'sampling_rate': sr1_orig, 'npts': window_samples_1 })).resample(resample_rate, no_filter=True).data tr2_d = Trace( data=tr2_d, header=Stats(header={ 'sampling_rate': sr2_orig, 'npts': window_samples_2 })).resample(resample_rate, no_filter=True).data # end if # STEP 6: Bandpass if (flo and fhi): tr1_d = bandpass(tr1_d, flo, fhi, sr1, corners=2, zerophase=True) tr2_d = bandpass(tr2_d, flo, fhi, sr2, corners=2, zerophase=True) # end if # STEP 7: time-domain normalization # clip to +/- 2*std if (clip_to_2std): std_tr1 = np.std(tr1_d) std_tr2 = np.std(tr2_d) clip_indices_tr1 = np.fabs(tr1_d) > 2 * std_tr1 clip_indices_tr2 = np.fabs(tr2_d) > 2 * std_tr2 tr1_d[clip_indices_tr1] = 2 * std_tr1 * np.sign( tr1_d[clip_indices_tr1]) tr2_d[clip_indices_tr2] = 2 * std_tr2 * np.sign( tr2_d[clip_indices_tr2]) # end if # 1-bit normalization if (one_bit_normalize): tr1_d = np.sign(tr1_d) tr2_d = np.sign(tr2_d) # end if # Apply Rhys Hawkins-style default time domain normalization if (clip_to_2std == 0 and one_bit_normalize == 0): # 0-mean tr1_d -= np.mean(tr1_d) tr2_d -= np.mean(tr2_d) # unit-std tr1_d /= np.std(tr1_d) tr2_d /= np.std(tr2_d) # end if # STEP 8: taper if (adjusted_taper_length > 0): tr1_d = taper( tr1_d, int(np.round(adjusted_taper_length * tr1_d.shape[0]))) tr2_d = taper( tr2_d, int(np.round(adjusted_taper_length * tr2_d.shape[0]))) # end if # STEP 9: spectral whitening if (whitening): tr1_d = whiten(tr1_d, sr1, window_freq=whitening_window_frequency) tr2_d = whiten(tr2_d, sr2, window_freq=whitening_window_frequency) # STEP 10: taper if (adjusted_taper_length > 0): tr1_d = taper( tr1_d, int( np.round(adjusted_taper_length * tr1_d.shape[0]))) tr2_d = taper( tr2_d, int( np.round(adjusted_taper_length * tr2_d.shape[0]))) # end if # end if # STEP 11: Final bandpass # apply zero-phase bandpass if (flo and fhi): tr1_d = bandpass(tr1_d, flo, fhi, sr1, corners=2, zerophase=True) tr2_d = bandpass(tr2_d, flo, fhi, sr2, corners=2, zerophase=True) # end if if (window_buffer_seconds): # extract window of interest from buffered window tr1_d = tr1_d[int(window_buffer_seconds * sr1):-int(window_buffer_seconds * sr1)] tr2_d = tr2_d[int(window_buffer_seconds * sr2):-int(window_buffer_seconds * sr2)] # end if # cross-correlate waveforms if (sr1 < sr2): fftlen2 = fftlen fftlen1 = int((fftlen2 * 1.0 * sr1) / sr) rf = zeropad_ba( fftn(zeropad(tr1_d, fftlen1), shape=[fftlen1]), fftlen2) * fftn(zeropad(ndflip(tr2_d), fftlen2), shape=[fftlen2]) elif (sr1 > sr2): fftlen1 = fftlen fftlen2 = int((fftlen1 * 1.0 * sr2) / sr) rf = fftn(zeropad(tr1_d, fftlen1), shape=[fftlen1]) * zeropad_ba( fftn(zeropad(ndflip(tr2_d), fftlen2), shape=[fftlen2]), fftlen1) else: rf = fftn(zeropad(tr1_d, fftlen), shape=[fftlen]) * fftn( zeropad(ndflip(tr2_d), fftlen), shape=[fftlen]) # end if if (not np.isnan(rf).any()): resl.append(rf) windowCount += 1 # end if # end if wtr1s += int( (window_samples_1 - 2 * window_buffer_seconds * sr1_orig) - (window_samples_1 - 2 * window_buffer_seconds * sr1_orig) * window_overlap) wtr2s += int( (window_samples_2 - 2 * window_buffer_seconds * sr2_orig) - (window_samples_2 - 2 * window_buffer_seconds * sr2_orig) * window_overlap) # end while (windows within interval) if (verbose > 1): if (logger): logger.info('\tProcessed %d windows in interval %d' % (windowCount, intervalCount)) # end fi intervalStartSeconds.append(itr1s / sr1_orig + tr1.stats.starttime.timestamp) intervalEndSeconds.append(itr1e / sr1_orig + tr1.stats.starttime.timestamp) itr1s = itr1e itr2s = itr2e intervalCount += 1 # Append an array of zeros if no windows were processed for the current interval if (windowCount == 0): resl.append(np.zeros(fftlen)) if (verbose > 1): if (logger): logger.info( '\tWarning: No windows processed due to gaps in data in current interval' ) # end if # end if windowsPerInterval.append(windowCount) if (windowCount > 0): mean = reduce((lambda tx, ty: tx + ty), resl) / float(windowCount) else: mean = reduce((lambda tx, ty: tx + ty), resl) # end if if (envelope_normalize): step = np.sign(np.fft.fftfreq(fftlen, 1.0 / sr)) mean = mean + step * mean # compute analytic # end if mean = ifftn(mean) if (envelope_normalize): # Compute magnitude of mean mean = np.abs(mean) normFactor = np.max(mean) # mean can be 0 for a null result if (normFactor > 0): mean /= normFactor # end if # end if resll.append(mean[:xcorlen]) # end while (iteration over intervals) if (len(resll)): return np.array(resll), np.array(windowsPerInterval), \ np.array(intervalStartSeconds, dtype='i8'), \ np.array(intervalEndSeconds, dtype='i8'), \ sr else: return None, None, None, None, None