def _calcresp(calfile, nfft, sampfreq): """ Calculate transfer function of known system. :type calfile: String :param calfile: file containing poles, zeros and scale factor for known system :returns: complex transfer function, array of frequencies """ # avoid top level dependency on gse2 try: from obspy.gse2.paz import readPaz except ImportError: msg = "Error during import from obspy.gse2. Please make " + \ "sure obspy.gse2 is installed properly." raise ImportError(msg) # calculate transfer function poles, zeros, scale_fac = readPaz(calfile) h, f = pazToFreqResp(poles, zeros, scale_fac, 1.0 / sampfreq, nfft, freq=True) return h, f
def update(self): """ This method should do everything to update the plot. """ try: # clear axes before anything else ax1 = self.ax1 ax1.clear() ax2 = self.ax2 ax2.clear() # plot theoretical responses from paz here paz = self.paz h, f = pazToFreqResp(paz['poles'], paz['zeros'], paz['gain'], self.spr, self.nfft, freq=True) ampl = abs(h) phase = np.unwrap(np.arctan2(-h.imag, h.real)) #take negative of imaginary part ax1.loglog(f, ampl, color="r") ax2.semilogx(f, phase, color="r", label='paz fit') # plot read in calibration output ax1.loglog(self.freq, self.ampl, color="b", ls="--") ax2.semilogx(self.freq, self.phase, color="b", ls="--", label='calibration output') ax2.legend() # update matplotlib canvas self.canv.draw() except: msg = "Problem during plot-update. Value ranges OK?" warnings.warn(msg)
def _getRespFromModel(self, pazModel, nfft, delta): ''' :param dictionary pazModel: dictionary or poles and zeros :param int nfft: :param delta: delta T between samples ''' # This function returns the response without normalization resp = pazToFreqResp(pazModel['poles'], pazModel['zeros'], 1, delta, nfft, freq=False) return resp
def _calcresp(calfile, nfft, sampfreq): """ Calculate transfer function of known system. :type calfile: String :param calfile: file containing poles, zeros and scale factor for known system :returns: complex transfer function, array of frequencies """ # calculate transfer function poles, zeros, scale_fac = readPaz(calfile) h, f = pazToFreqResp(poles, zeros, scale_fac, 1.0 / sampfreq, nfft, freq=True) return h, f
def update(self): """ This method should do everything to update the plot. """ try: # clear axes before anything else ax1 = self.ax1 ax1.clear() ax2 = self.ax2 ax2.clear() # plot theoretical responses from paz here paz = self.paz h, f = pazToFreqResp(paz['poles'], paz['zeros'], paz['gain'], self.spr, self.nfft, freq=True) ampl = abs(h) #compute the residuum resid = 0 ampl1 = self.ampl[(f > self.box_lfreq.value()) & (f < self.box_hfreq.value())] ampl2 = ampl[(f > self.box_lfreq.value()) & (f < self.box_hfreq.value())] ampl1s = ampl1 - ampl1.mean() resid = (((ampl2 - ampl1)**2).sum()) / ( (ampl1.mean())**2 * len(ampl1)) res = "Residuum: %f" % (resid) phase = np.unwrap(np.arctan2( -h.imag, h.real)) #take negative of imaginary part ax1.loglog(f, ampl, color="r") ax2.semilogx(f, phase, color="r", label=res) # plot read in calibration output ax1.loglog(self.freq, self.ampl, color="b", ls="--") # ax2.semilogx(self.freq, self.phase, color="b", ls="--", label='calibration output') ax2.semilogx(self.freq, self.phase, color="b", ls="--") ax2.legend() # update matplotlib canvas self.canv.draw() except: msg = "Problem during plot-update. Value ranges OK?" warnings.warn(msg)
def update(self): """ This method should do everything to update the plot. """ try: # clear axes before anything else ax1 = self.ax1 ax1.clear() ax2 = self.ax2 ax2.clear() # plot theoretical responses from paz here paz = self.paz h, f = pazToFreqResp(paz['poles'], paz['zeros'], paz['gain'], self.spr, self.nfft, freq=True) ampl = abs(h) #compute the residuum resid = 0 ampl1 = self.ampl[(f>self.box_lfreq.value()) & (f<self.box_hfreq.value())] ampl2 = ampl[(f>self.box_lfreq.value()) & (f<self.box_hfreq.value())] ampl1s = ampl1 - ampl1.mean() resid = (((ampl2 - ampl1) ** 2).sum()) / ((ampl1.mean())**2 * len(ampl1)) res = "Residuum: %f"%(resid) phase = np.unwrap(np.arctan2(-h.imag, h.real)) #take negative of imaginary part ax1.loglog(f, ampl, color="r") ax2.semilogx(f, phase, color="r", label=res) # plot read in calibration output ax1.loglog(self.freq, self.ampl, color="b", ls="--") # ax2.semilogx(self.freq, self.phase, color="b", ls="--", label='calibration output') ax2.semilogx(self.freq, self.phase, color="b",ls="--") ax2.legend() # update matplotlib canvas self.canv.draw() except: msg = "Problem during plot-update. Value ranges OK?" warnings.warn(msg)
def update(self): """ This method should do everything to update the plot. """ try: # clear axes before anything else ax1 = self.ax1 ax1.clear() ax2 = self.ax2 ax2.clear() # plot theoretical responses from paz here paz = self.paz h, f = pazToFreqResp(paz['poles'], paz['zeros'], paz['gain'], self.spr, self.nfft, freq=True) ampl = abs(h) phase = np.unwrap(np.arctan2( -h.imag, h.real)) #take negative of imaginary part ax1.loglog(f, ampl, color="r") ax2.semilogx(f, phase, color="r", label='paz fit') # plot read in calibration output ax1.loglog(self.freq, self.ampl, color="b", ls="--") ax2.semilogx(self.freq, self.phase, color="b", ls="--", label='calibration output') ax2.legend() # update matplotlib canvas self.canv.draw() except: msg = "Problem during plot-update. Value ranges OK?" warnings.warn(msg)
import numpy as np import matplotlib.pyplot as plt from obspy.signal import pazToFreqResp poles = [-4.440 + 4.440j, -4.440 - 4.440j, -1.083 + 0.0j] zeros = [0.0 + 0.0j, 0.0 + 0.0j, 0.0 + 0.0j] scale_fac = 0.4 h, f = pazToFreqResp(poles, zeros, scale_fac, 0.005, 16384, freq=True) plt.figure() plt.subplot(121) plt.loglog(f, abs(h)) plt.xlabel('Frequency [Hz]') plt.ylabel('Amplitude') plt.subplot(122) # take negative of imaginary part phase = np.unwrap(np.arctan2(-h.imag, h.real)) plt.semilogx(f, phase) plt.xlabel('Frequency [Hz]') plt.ylabel('Phase [radian]') # title, centered above both subplots plt.suptitle('Frequency Response of LE-3D/1s Seismometer') # make more room in between subplots for the ylabel of right plot plt.subplots_adjust(wspace=0.3) plt.show()
def computeresp(resp,delta,lenfft): respval = pazToFreqResp(resp['poles'],resp['zeros'],resp['sensitivity'],t_samp = delta, nfft=lenfft,freq = False) respval = numpy.absolute(respval*numpy.conjugate(respval)) respval = respval[1:] return respval
def single_comparison(): """ one by one comparison of the waveforms in the first path with the second path. """ client = Client() global input # identity of the waveforms (first and second paths) to be compared with each other identity_all = input['net'] + '.' + input['sta'] + '.' + \ input['loc'] + '.' + input['cha'] ls_first = glob.glob(os.path.join(input['first_path'], identity_all)) ls_second = glob.glob(os.path.join(input['second_path'], identity_all)) for i in range(0, len(ls_first)): try: tr1 = read(ls_first[i])[0] if input['phase'] != 'N': evsta_dist = util.locations2degrees(lat1 = tr1.stats.sac.evla, \ long1 = tr1.stats.sac.evlo, lat2 = tr1.stats.sac.stla, \ long2 = tr1.stats.sac.stlo) taup_tt = taup.getTravelTimes(delta=evsta_dist, depth=tr1.stats.sac.evdp) phase_exist = 'N' for tt_item in taup_tt: if tt_item['phase_name'] == input['phase']: print 'Requested phase:' print input['phase'] print '------' print tt_item['phase_name'] print 'exists in the waveform!' print '-----------------------' t_phase = tt_item['time'] phase_exist = 'Y' break if phase_exist != 'Y': continue # identity of the current waveform identity = tr1.stats.network + '.' + tr1.stats.station + '.' + \ tr1.stats.location + '.' + tr1.stats.channel # tr1: first path, tr2: second path, tr3: Raw data #tr3 = read(os.path.join(input['first_path'], '..', 'BH_RAW', identity))[0] if input['resp_paz'] == 'Y': response_file = os.path.join(input['first_path'], '..', 'Resp/RESP.' + identity) # Extract the PAZ info from response file paz = readRESP(response_file, unit=input['corr_unit']) poles = paz['poles'] zeros = paz['zeros'] scale_fac = paz['gain'] sensitivity = paz['sensitivity'] print paz # Convert Poles and Zeros (PAZ) to frequency response. h, f = pazToFreqResp(poles, zeros, scale_fac, \ 1./tr1.stats.sampling_rate, tr1.stats.npts*2, freq=True) # Use the evalresp library to extract # instrument response information from a SEED RESP-file. resp = invsim.evalresp(t_samp = 1./tr1.stats.sampling_rate, \ nfft = tr1.stats.npts*2, filename = response_file, \ date = tr1.stats.starttime, units = input['corr_unit'].upper()) # Keep the current identity in a new variable id_name = identity try: tr2 = read(os.path.join(input['second_path'], identity))[0] except Exception, error: # if it is not possible to read the identity in the second path # then change the network part of the identity based on # correction unit identity = input['corr_unit'] + '.' + tr1.stats.station + '.' + \ tr1.stats.location + '.' + tr1.stats.channel tr2 = read(os.path.join(input['second_path'], identity))[0] if input['resample'] != 'N': print 'WARNING: you are using resample!!!' tr1.resample(input['resample']) tr2.resample(input['resample']) if input['tw'] == 'Y': t_cut_1 = tr1.stats.starttime + t_phase - input['preset'] t_cut_2 = tr1.stats.starttime + t_phase + input['offset'] tr1.trim(starttime=t_cut_1, endtime=t_cut_2) t_cut_1 = tr2.stats.starttime + t_phase - input['preset'] t_cut_2 = tr2.stats.starttime + t_phase + input['offset'] tr2.trim(starttime=t_cut_1, endtime=t_cut_2) if input['hlfilter'] == 'Y': tr1.filter('lowpass', freq=input['hfreq'], corners=2) tr2.filter('lowpass', freq=input['hfreq'], corners=2) tr1.filter('highpass', freq=input['lfreq'], corners=2) tr2.filter('highpass', freq=input['lfreq'], corners=2) # normalization of all three waveforms to the # max(max(tr1), max(tr2), max(tr3)) to keep the scales #maxi = max(abs(tr1.data).max(), abs(tr2.data).max(), abs(tr3.data).max()) #maxi = max(abs(tr1.data).max(), abs(tr2.data).max()) #tr1_data = tr1.data/abs(maxi) #tr2_data = tr2.data/abs(maxi) #tr3_data = tr3.data/abs(maxi) tr1_data = tr1.data / abs(max(tr1.data)) tr2_data = tr2.data / abs(max(tr2.data)) #tr1_data = tr1.data #tr2_data = tr2.data*1e9 print max(tr1.data) print max(tr2.data) # create time arrays for tr1, tr2 and tr3 time_tr1 = np.arange(0, tr1.stats.npts/tr1.stats.sampling_rate, \ 1./tr1.stats.sampling_rate) time_tr2 = np.arange(0, tr2.stats.npts/tr2.stats.sampling_rate, \ 1./tr2.stats.sampling_rate) #time_tr3 = np.arange(0, tr3.stats.npts/tr3.stats.sampling_rate, \ # 1./tr3.stats.sampling_rate) # label for plotting label_tr1 = ls_first[i].split('/')[-2] label_tr2 = ls_second[i].split('/')[-2] label_tr3 = 'RAW' if input['resp_paz'] == 'Y': # start plotting plt.figure() plt.subplot2grid((3, 4), (0, 0), colspan=4, rowspan=2) #plt.subplot(211) plt.plot(time_tr1, tr1_data, color='blue', label=label_tr1, lw=3) plt.plot(time_tr2, tr2_data, color='red', label=label_tr2, lw=3) #plt.plot(time_tr3, tr3_data, color = 'black', ls = '--', label = label_tr3) plt.xlabel('Time (sec)', fontsize='xx-large', weight='bold') if input['corr_unit'] == 'dis': ylabel_str = 'Relative Displacement' elif input['corr_unit'] == 'vel': ylabel_str = 'Relative Vel' elif input['corr_unit'] == 'acc': ylabel_str = 'Relative Acc' plt.ylabel(ylabel_str, fontsize='xx-large', weight='bold') plt.xticks(fontsize='xx-large', weight='bold') plt.yticks(fontsize='xx-large', weight='bold') plt.legend(loc=1, prop={'size': 20}) #-------------------Cross Correlation # 5 seconds as total length of samples to shift for cross correlation. cc_np = tr1.stats.sampling_rate * 3 np_shift, coeff = cross_correlation.xcorr(tr1, tr2, int(cc_np)) t_shift = float(np_shift) / tr1.stats.sampling_rate print "Cross Correlation:" print "Shift: " + str(t_shift) print "Coefficient: " + str(coeff) plt.title('Single Comparison' + '\n' + str(t_shift) + \ ' sec , coeff: ' + str(round(coeff, 5)) + \ '\n' + id_name, \ fontsize = 'xx-large', weight = 'bold') if input['resp_paz'] == 'Y': # ----------------------- #plt.subplot(223) plt.subplot2grid((3, 4), (2, 0), colspan=2) ''' plt.plot(np.log10(f), np.log10(abs(resp)/(sensitivity*sensitivity)), \ color = 'blue', label = 'RESP', lw=3) plt.plot(np.log10(f), np.log10(abs(h)/sensitivity), \ color = 'red', label = 'PAZ', lw=3) ''' plt.loglog(f, abs(resp)/(sensitivity*sensitivity), \ color = 'blue', label = 'RESP', lw=3) plt.loglog(f, abs(h)/sensitivity, \ color = 'red', label = 'PAZ', lw=3) #for j in [0.008, 0.012, 0.025, 0.5, 1, 2, 3, 4]: for j in [0]: plt.axvline(np.log10(j), linestyle='--') #plt.xlabel('Frequency [Hz]\n(power of 10)', fontsize = 'xx-large', weight = 'bold') #plt.ylabel('Amplitude\n (power of 10)', fontsize = 'xx-large', weight = 'bold') plt.xlabel('Frequency [Hz]', fontsize='xx-large', weight='bold') plt.ylabel('Amplitude', fontsize='xx-large', weight='bold') plt.xticks(fontsize='xx-large', weight='bold') #plt.yticks = MaxNLocator(nbins=4) plt.yticks(fontsize='xx-large', weight='bold') plt.legend(loc=2, prop={'size': 20}) # ----------------------- #plt.subplot(224) plt.subplot2grid((3, 4), (2, 2), colspan=2) #take negative of imaginary part phase_paz = np.unwrap(np.arctan2(h.imag, h.real)) phase_resp = np.unwrap(np.arctan2(resp.imag, resp.real)) #plt.plot(np.log10(f), phase_resp, color = 'blue', label = 'RESP', lw=3) #plt.plot(np.log10(f), phase_paz, color = 'red', label = 'PAZ', lw=3) plt.semilogx(f, phase_resp, color='blue', label='RESP', lw=3) plt.semilogx(f, phase_paz, color='red', label='PAZ', lw=3) #for j in [0.008, 0.012, 0.025, 0.5, 1, 2, 3, 4]: for j in [0.0]: plt.axvline(np.log10(j), linestyle='--') #plt.xlabel('Frequency [Hz]\n(power of 10)', fontsize = 'xx-large', weight = 'bold') plt.xlabel('Frequency [Hz]', fontsize='xx-large', weight='bold') plt.ylabel('Phase [radian]', fontsize='xx-large', weight='bold') plt.xticks(fontsize='xx-large', weight='bold') plt.yticks(fontsize='xx-large', weight='bold') plt.legend(loc=3, prop={'size': 20}) # title, centered above both subplots # make more room in between subplots for the ylabel of right plot plt.subplots_adjust(wspace=0.4, hspace=0.3) """ # ----------------------- plt.subplot(325) plt.plot(np.log10(f), np.log10(abs(resp)/(sensitivity*sensitivity)) - \ np.log10(abs(h)/sensitivity), \ color = 'black', label = 'RESP - PAZ') for j in [0.008, 0.012, 0.025, 0.5, 1, 2, 3, 4]: plt.axvline(np.log10(j), linestyle = '--') plt.xlabel('Frequency [Hz] (power of 10)') plt.ylabel('Amplitude (power of 10)') plt.legend() # ----------------------- plt.subplot(326) #take negative of imaginary part phase_paz = np.unwrap(np.arctan2(h.imag, h.real)) phase_resp = np.unwrap(np.arctan2(resp.imag, resp.real)) plt.plot(np.log10(f), np.log10(phase_resp) - np.log10(phase_paz), \ color = 'black', label = 'RESP - PAZ') for j in [0.008, 0.012, 0.025, 0.5, 1, 2, 3, 4]: plt.axvline(np.log10(j), linestyle = '--') plt.xlabel('Frequency [Hz] (power of 10)') plt.ylabel('Phase [radian] (power of 10)') plt.legend() # title, centered above both subplots # make more room in between subplots for the ylabel of right plot plt.subplots_adjust(wspace=0.3) """ plt.show() print str(i + 1) + '/' + str(len(ls_first)) print ls_first[i] print '------------------' wait = raw_input(id_name) print '***************************' except Exception, error: print '##################' print error print '##################'
def plot_xml_response(input_dics): """ plot the transfer function of stationXML file(s) :param input_dics: :return: """ plt.rc('font', family='serif') print('[INFO] plotting StationXML file/files in: %s' % \ input_dics['datapath']) if not os.path.isdir('./stationxml_plots'): print('[INFO] creating stationxml_plots directory...') os.mkdir('./stationxml_plots') # assign the input_dics parameters to the running parameters: stxml_dir = input_dics['datapath'] plotxml_datetime = input_dics['plotxml_date'] min_freq = input_dics['plotxml_min_freq'] output = input_dics['plotxml_output'] if 'dis' in output.lower(): output = 'DISP' elif 'vel' in output.lower(): output = 'VEL' elif 'acc' in output.lower(): output = 'ACC' else: output = output.upper() start_stage = input_dics['plotxml_start_stage'] end_stage_input = input_dics['plotxml_end_stage'] percentage = input_dics['plotxml_percentage']/100. threshold = input_dics['plotxml_phase_threshold'] plot_response = input_dics['plotxml_response'] plotstage12 = input_dics['plotxml_plotstage12'] plotpaz = input_dics['plotxml_paz'] plotallstages = input_dics['plotxml_allstages'] plot_map_compare = input_dics['plotxml_map_compare'] if os.path.isfile(stxml_dir): addxml_all = glob.glob(os.path.join(stxml_dir)) elif os.path.isdir(stxml_dir): addxml_all = glob.glob(os.path.join(stxml_dir, 'STXML.*')) else: try: addxml_all = glob.glob(os.path.join(stxml_dir)) except Exception as error: print('[ERROR] %s' % error) sys.exit('[ERROR] wrong address: %s' % stxml_dir) addxml_all.sort() sta_lat = [] sta_lon = [] latlon_color = [] report_fio = open(os.path.join('stationxml_plots', 'report_stationxml'), 'wt') report_fio.writelines('channel_id\t\t\t\t%(phase_diff)\t\t' 'abs(max_diff)\tlat\t\t\tlon\t\t\tdatetime\t' 'decimation delay\tdecimation corr\n') report_fio.close() add_counter = 0 for addxml in addxml_all: end_stage = end_stage_input add_counter += 1 print(40*'-') print('%s/%s' % (add_counter, len(addxml_all))) try: xml_inv = read_inventory(addxml, format='stationXML') print("[STATIONXML] %s" % addxml) # we only take into account the first channel... cha_name = xml_inv.get_contents()['channels'][0] if plotxml_datetime: cha_date = plotxml_datetime else: cha_date = xml_inv.networks[0][0][-1].start_date print('[INFO] plotxml_date has not been set, the start_date ' \ 'of the last channel in stationXML file will be used ' \ 'instead: %s' % cha_date) xml_response = xml_inv.get_response(cha_name, cha_date + 0.1) if xml_inv[0][0][0].sample_rate: sampling_rate = xml_inv[0][0][0].sample_rate else: for stage in xml_response.response_stages[::-1]: if (stage.decimation_input_sample_rate is not None) and\ (stage.decimation_factor is not None): sampling_rate = (stage.decimation_input_sample_rate / stage.decimation_factor) break t_samp = 1.0 / sampling_rate nyquist = sampling_rate / 2.0 nfft = int(sampling_rate / min_freq) end_stage = min(len(xml_response.response_stages), end_stage) if plotallstages: plot_xml_plotallstages(xml_response, t_samp, nyquist, nfft, min_freq, output, start_stage, end_stage, cha_name) try: cpx_response, freq = xml_response.get_evalresp_response( t_samp=t_samp, nfft=nfft, output=output, start_stage=start_stage, end_stage=end_stage) cpx_12, freq = xml_response.get_evalresp_response( t_samp=t_samp, nfft=nfft, output=output, start_stage=1, end_stage=2) except Exception as error: print('[WARNING] %s' % error) continue paz, decimation_delay, decimation_correction = \ convert_xml_paz(xml_response, output, cha_name, cha_date) if not paz: continue h, f = pazToFreqResp(paz['poles'], paz['zeros'], paz['gain'], 1./sampling_rate, nfft, freq=True) phase_resp = np.angle(cpx_response) phase_12 = np.angle(cpx_12) if plot_response: plt.figure(figsize=(20, 10)) plt.suptitle(cha_name, size=24, weight='bold') if plotpaz or plotstage12: plt.subplot(2, 2, 1) else: plt.subplot(2, 1, 1) plt.loglog(freq, abs(cpx_response), color='blue', lw=3, label='full-resp') if plotstage12: plt.loglog(freq, abs(cpx_12), ls='--', color='black', lw=3, label='Stage1,2') if plotpaz: plt.loglog(f, abs(h)*paz['sensitivity'], color='red', lw=3, label='PAZ') plt.axvline(nyquist, ls="--", color='black', lw=3) plt.ylabel('Amplitude', size=24, weight='bold') plt.xticks(size=18, weight='bold') plt.yticks(size=18, weight='bold') plt.xlim(xmin=min_freq, xmax=nyquist+5) plt.ylim(ymax=max(1.2*abs(cpx_response))) plt.legend(loc=0, prop={'size': 18, 'weight': 'bold'}) plt.grid() if plotpaz or plotstage12: plt.subplot(2, 2, 3) else: plt.subplot(2, 1, 2) plt.semilogx(freq, phase_resp, color='blue', lw=3, label='full-resp') if plotstage12: plt.semilogx(freq, phase_12, ls='--', color='black', lw=3, label='Stage1,2') if plotpaz: plt.semilogx(f, np.angle(h), color='red', lw=3, label='PAZ') plt.axvline(nyquist, ls="--", color='black', lw=3) plt.xlabel('Frequency [Hz]', size=24, weight='bold') plt.ylabel('Phase [rad]', size=24, weight='bold') plt.xticks(size=18, weight='bold') plt.yticks(size=18, weight='bold') plt.xlim(xmin=min_freq, xmax=nyquist+5) plt.legend(loc=0, prop={'size': 18, 'weight': 'bold'}) plt.grid() if plotstage12 or plotpaz: ax_222 = plt.subplot(2, 2, 2) y_label = 'Amplitude ratio' if plotstage12: plt.loglog(freq, abs(abs(cpx_response) / abs(cpx_12)), '--', color='black', lw=3, label='|full-resp|/|Stage1,2|') y_label = '|full-resp|/|Stage1,2|' amp_ratio = 1 if plotpaz: amp_ratio = abs(abs(cpx_response) / (abs(h)*paz['sensitivity'])) plt.loglog(f, amp_ratio, color='red', lw=3, label='|full-resp|/|PAZ|') y_label = '|full-resp|/|PAZ|' plt.axvline(nyquist, ls="--", color='black', lw=3) plt.axvline(percentage*nyquist, ls="--", color='black', lw=3) plt.ylabel(y_label, size=24, weight='bold') plt.xticks(size=18, weight='bold') plt.yticks(size=18, weight='bold') plt.xlim(xmin=min_freq, xmax=nyquist+5) plt.ylim(ymax=1.2*max(amp_ratio[np.logical_not( np.isnan(amp_ratio))])) plt.grid() ax_224 = plt.subplot(2, 2, 4) y_label = 'Phase difference [rad]' if plotstage12: plt.semilogx(freq, abs(phase_resp - phase_12), color='black', ls='--', lw=3, label='|full-resp - Stage1,2|') y_label = '|full-resp - Stage1,2| [rad]' if plotpaz: plt.semilogx(freq, abs(phase_resp - np.angle(h)), color='red', lw=3, label='|full-resp - PAZ|') y_label = '|full-resp - PAZ|' plt.axvline(nyquist, ls="--", color='black', lw=3) plt.axvline(percentage*nyquist, ls="--", color='black', lw=3) plt.xlabel('Frequency [Hz]', size=24, weight='bold') plt.ylabel(y_label, size=24, weight='bold') plt.xticks(size=18, weight='bold') plt.yticks(size=18, weight='bold') plt.xlim(xmin=min_freq, xmax=nyquist+5) plt.grid() plt.savefig(os.path.join('stationxml_plots', cha_name + '.png')) plt.close() # compare = abs(phase[:int(0.8*len(phase))] - # np.angle(h[:int(0.8*len(phase))])) # if len(compare[compare>0.1]) > 0: # lat_red.append(xml_inv.get_coordinates(cha_name)['latitude']) # lon_red.append(xml_inv.get_coordinates(cha_name)['longitude']) # print cha_name # print paz # else: # lat_blue.append(xml_inv.get_coordinates(cha_name)['latitude']) # lon_blue.append(xml_inv.get_coordinates(cha_name)['longitude']) phase_resp_check = phase_resp[:int(percentage*len(phase_resp))] phase_h_check = np.angle(h)[:int(percentage*len(np.angle(h)))] if not len(phase_resp_check) == len(phase_h_check): sys.exit('[ERROR] lengths of phase responses do not match: ' '%s (StationXML) != %s (PAZ)' % (len(phase_resp_check), len(phase_h_check))) compare = abs(phase_resp_check - phase_h_check) percent_compare = \ float(len(compare[compare >= 0.05]))/len(compare)*100 latlondep = get_coordinates(xml_inv.networks[0], cha_name, cha_date + 0.1) sta_lat.append(latlondep['latitude']) sta_lon.append(latlondep['longitude']) d_c = np.sum(decimation_delay) - np.sum(decimation_correction) if not d_c == 0: latlon_color.append(0.) else: latlon_color.append(percent_compare) if percent_compare >= threshold: plot_xml_plotallstages(xml_response, t_samp, nyquist, nfft, min_freq, output, start_stage, end_stage, cha_name) report_fio = open(os.path.join('stationxml_plots', 'report_stationxml'), 'at') report_fio.writelines( '%s\t\t\t%6.2f\t\t\t%6.2f\t\t\t%6.2f\t\t%7.2f\t\t%s\t%s\t%s\n' % (cha_name, round(percent_compare, 2), round(max(abs(compare)), 2), round(sta_lat[-1], 2), round(sta_lon[-1], 2), cha_date, np.sum(decimation_delay), np.sum(decimation_correction))) report_fio.close() except Exception as error: print('[Exception] %s' % error) if plot_map_compare: from mpl_toolkits.basemap import Basemap plt.figure() m = Basemap(projection='robin', lon_0=input_dics['plot_lon0'], lat_0=0) m.fillcontinents() m.drawparallels(np.arange(-90., 120., 30.)) m.drawmeridians(np.arange(0., 420., 60.)) m.drawmapboundary() x, y = m(sta_lon, sta_lat) m.scatter(x, y, 100, c=latlon_color, marker="v", edgecolor='none', zorder=10, cmap='rainbow') plt.colorbar(orientation='horizontal') plt.savefig(os.path.join('stationxml_plots', 'compare_plots.png')) plt.show() raw_input_built('Press Enter...') sys.exit('[EXIT] obspyDMT finished normally...')
def getRespFromModel(pazModel,nfft,delta,norm): #This function returns the response without normalization resp = pazToFreqResp(pazModel['poles'],pazModel['zeros'],1, \ tracein.stats.delta, nfft, freq=False) resp = resp[1:] return resp
} # Read in the data tr = read("loc_RJOB20050831023349.z")[0] # Do the instrument correction data_corr = seisSim(tr.data, tr.stats.sampling_rate, le3d, inst_sim=PAZ_WOOD_ANDERSON, water_level=60.0) # Just for visualization, calculate transferfuction in frequency domain trans, freq = pazToFreqResp(le3d['poles'], le3d['zeros'], le3d['gain'], 1. / tr.stats.sampling_rate, 2**12, freq=True) # # The plotting part # time = np.arange(0, tr.stats.npts) / tr.stats.sampling_rate plt.figure() plt.subplot(211) plt.plot(time, tr.data, label="Original Data") plt.legend() plt.subplot(212) plt.plot(time, data_corr, label="Wood Anderson Simulated Data") plt.legend() plt.xlabel("Time [s]")
def single_comparison(): """ one by one comparison of the waveforms in the first path with the second path. """ client = Client() global input # identity of the waveforms (first and second paths) to be compared with each other identity_all = input['net'] + '.' + input['sta'] + '.' + \ input['loc'] + '.' + input['cha'] ls_first = glob.glob(os.path.join(input['first_path'], identity_all)) ls_second = glob.glob(os.path.join(input['second_path'], identity_all)) for i in range(0, len(ls_first)): try: tr1 = read(ls_first[i])[0] if input['phase'] != 'N': evsta_dist = util.locations2degrees(lat1 = tr1.stats.sac.evla, \ long1 = tr1.stats.sac.evlo, lat2 = tr1.stats.sac.stla, \ long2 = tr1.stats.sac.stlo) taup_tt = taup.getTravelTimes(delta = evsta_dist, depth = tr1.stats.sac.evdp) phase_exist = 'N' for tt_item in taup_tt: if tt_item['phase_name'] == input['phase']: print 'Requested phase:' print input['phase'] print '------' print tt_item['phase_name'] print 'exists in the waveform!' print '-----------------------' t_phase = tt_item['time'] phase_exist = 'Y' break if phase_exist != 'Y': continue # identity of the current waveform identity = tr1.stats.network + '.' + tr1.stats.station + '.' + \ tr1.stats.location + '.' + tr1.stats.channel # tr1: first path, tr2: second path, tr3: Raw data #tr3 = read(os.path.join(input['first_path'], '..', 'BH_RAW', identity))[0] if input['resp_paz'] == 'Y': response_file = os.path.join(input['first_path'], '..', 'Resp/RESP.' + identity) # Extract the PAZ info from response file paz = readRESP(response_file, unit = input['corr_unit']) poles = paz['poles'] zeros = paz['zeros'] scale_fac = paz['gain'] sensitivity = paz['sensitivity'] print paz # Convert Poles and Zeros (PAZ) to frequency response. h, f = pazToFreqResp(poles, zeros, scale_fac, \ 1./tr1.stats.sampling_rate, tr1.stats.npts*2, freq=True) # Use the evalresp library to extract # instrument response information from a SEED RESP-file. resp = invsim.evalresp(t_samp = 1./tr1.stats.sampling_rate, \ nfft = tr1.stats.npts*2, filename = response_file, \ date = tr1.stats.starttime, units = input['corr_unit'].upper()) # Keep the current identity in a new variable id_name = identity try: tr2 = read(os.path.join(input['second_path'], identity))[0] except Exception, error: # if it is not possible to read the identity in the second path # then change the network part of the identity based on # correction unit identity = input['corr_unit'] + '.' + tr1.stats.station + '.' + \ tr1.stats.location + '.' + tr1.stats.channel tr2 = read(os.path.join(input['second_path'], identity))[0] if input['resample'] != 'N': print 'WARNING: you are using resample!!!' tr1.resample(input['resample']) tr2.resample(input['resample']) if input['tw'] == 'Y': t_cut_1 = tr1.stats.starttime + t_phase - input['preset'] t_cut_2 = tr1.stats.starttime + t_phase + input['offset'] tr1.trim(starttime = t_cut_1, endtime = t_cut_2) t_cut_1 = tr2.stats.starttime + t_phase - input['preset'] t_cut_2 = tr2.stats.starttime + t_phase + input['offset'] tr2.trim(starttime = t_cut_1, endtime = t_cut_2) if input['hlfilter'] == 'Y': tr1.filter('lowpass', freq=input['hfreq'], corners=2) tr2.filter('lowpass', freq=input['hfreq'], corners=2) tr1.filter('highpass', freq=input['lfreq'], corners=2) tr2.filter('highpass', freq=input['lfreq'], corners=2) # normalization of all three waveforms to the # max(max(tr1), max(tr2), max(tr3)) to keep the scales #maxi = max(abs(tr1.data).max(), abs(tr2.data).max(), abs(tr3.data).max()) #maxi = max(abs(tr1.data).max(), abs(tr2.data).max()) #tr1_data = tr1.data/abs(maxi) #tr2_data = tr2.data/abs(maxi) #tr3_data = tr3.data/abs(maxi) tr1_data = tr1.data/abs(max(tr1.data)) tr2_data = tr2.data/abs(max(tr2.data)) #tr1_data = tr1.data #tr2_data = tr2.data*1e9 print max(tr1.data) print max(tr2.data) # create time arrays for tr1, tr2 and tr3 time_tr1 = np.arange(0, tr1.stats.npts/tr1.stats.sampling_rate, \ 1./tr1.stats.sampling_rate) time_tr2 = np.arange(0, tr2.stats.npts/tr2.stats.sampling_rate, \ 1./tr2.stats.sampling_rate) #time_tr3 = np.arange(0, tr3.stats.npts/tr3.stats.sampling_rate, \ # 1./tr3.stats.sampling_rate) # label for plotting label_tr1 = ls_first[i].split('/')[-2] label_tr2 = ls_second[i].split('/')[-2] label_tr3 = 'RAW' if input['resp_paz'] == 'Y': # start plotting plt.figure() plt.subplot2grid((3,4), (0,0), colspan=4, rowspan=2) #plt.subplot(211) plt.plot(time_tr1, tr1_data, color = 'blue', label = label_tr1, lw=3) plt.plot(time_tr2, tr2_data, color = 'red', label = label_tr2, lw=3) #plt.plot(time_tr3, tr3_data, color = 'black', ls = '--', label = label_tr3) plt.xlabel('Time (sec)', fontsize = 'xx-large', weight = 'bold') if input['corr_unit'] == 'dis': ylabel_str = 'Relative Displacement' elif input['corr_unit'] == 'vel': ylabel_str = 'Relative Vel' elif input['corr_unit'] == 'acc': ylabel_str = 'Relative Acc' plt.ylabel(ylabel_str, fontsize = 'xx-large', weight = 'bold') plt.xticks(fontsize = 'xx-large', weight = 'bold') plt.yticks(fontsize = 'xx-large', weight = 'bold') plt.legend(loc=1,prop={'size':20}) #-------------------Cross Correlation # 5 seconds as total length of samples to shift for cross correlation. cc_np = tr1.stats.sampling_rate * 3 np_shift, coeff = cross_correlation.xcorr(tr1, tr2, int(cc_np)) t_shift = float(np_shift)/tr1.stats.sampling_rate print "Cross Correlation:" print "Shift: " + str(t_shift) print "Coefficient: " + str(coeff) plt.title('Single Comparison' + '\n' + str(t_shift) + \ ' sec , coeff: ' + str(round(coeff, 5)) + \ '\n' + id_name, \ fontsize = 'xx-large', weight = 'bold') if input['resp_paz'] == 'Y': # ----------------------- #plt.subplot(223) plt.subplot2grid((3,4), (2,0), colspan=2) ''' plt.plot(np.log10(f), np.log10(abs(resp)/(sensitivity*sensitivity)), \ color = 'blue', label = 'RESP', lw=3) plt.plot(np.log10(f), np.log10(abs(h)/sensitivity), \ color = 'red', label = 'PAZ', lw=3) ''' plt.loglog(f, abs(resp)/(sensitivity*sensitivity), \ color = 'blue', label = 'RESP', lw=3) plt.loglog(f, abs(h)/sensitivity, \ color = 'red', label = 'PAZ', lw=3) #for j in [0.008, 0.012, 0.025, 0.5, 1, 2, 3, 4]: for j in [0]: plt.axvline(np.log10(j), linestyle = '--') #plt.xlabel('Frequency [Hz]\n(power of 10)', fontsize = 'xx-large', weight = 'bold') #plt.ylabel('Amplitude\n (power of 10)', fontsize = 'xx-large', weight = 'bold') plt.xlabel('Frequency [Hz]', fontsize = 'xx-large', weight = 'bold') plt.ylabel('Amplitude', fontsize = 'xx-large', weight = 'bold') plt.xticks(fontsize = 'xx-large', weight = 'bold') #plt.yticks = MaxNLocator(nbins=4) plt.yticks(fontsize = 'xx-large', weight = 'bold') plt.legend(loc=2,prop={'size':20}) # ----------------------- #plt.subplot(224) plt.subplot2grid((3,4), (2,2), colspan=2) #take negative of imaginary part phase_paz = np.unwrap(np.arctan2(h.imag, h.real)) phase_resp = np.unwrap(np.arctan2(resp.imag, resp.real)) #plt.plot(np.log10(f), phase_resp, color = 'blue', label = 'RESP', lw=3) #plt.plot(np.log10(f), phase_paz, color = 'red', label = 'PAZ', lw=3) plt.semilogx(f, phase_resp, color = 'blue', label = 'RESP', lw=3) plt.semilogx(f, phase_paz, color = 'red', label = 'PAZ', lw=3) #for j in [0.008, 0.012, 0.025, 0.5, 1, 2, 3, 4]: for j in [0.0]: plt.axvline(np.log10(j), linestyle = '--') #plt.xlabel('Frequency [Hz]\n(power of 10)', fontsize = 'xx-large', weight = 'bold') plt.xlabel('Frequency [Hz]', fontsize = 'xx-large', weight = 'bold') plt.ylabel('Phase [radian]', fontsize = 'xx-large', weight = 'bold') plt.xticks(fontsize = 'xx-large', weight = 'bold') plt.yticks(fontsize = 'xx-large', weight = 'bold') plt.legend(loc=3,prop={'size':20}) # title, centered above both subplots # make more room in between subplots for the ylabel of right plot plt.subplots_adjust(wspace=0.4, hspace=0.3) """ # ----------------------- plt.subplot(325) plt.plot(np.log10(f), np.log10(abs(resp)/(sensitivity*sensitivity)) - \ np.log10(abs(h)/sensitivity), \ color = 'black', label = 'RESP - PAZ') for j in [0.008, 0.012, 0.025, 0.5, 1, 2, 3, 4]: plt.axvline(np.log10(j), linestyle = '--') plt.xlabel('Frequency [Hz] (power of 10)') plt.ylabel('Amplitude (power of 10)') plt.legend() # ----------------------- plt.subplot(326) #take negative of imaginary part phase_paz = np.unwrap(np.arctan2(h.imag, h.real)) phase_resp = np.unwrap(np.arctan2(resp.imag, resp.real)) plt.plot(np.log10(f), np.log10(phase_resp) - np.log10(phase_paz), \ color = 'black', label = 'RESP - PAZ') for j in [0.008, 0.012, 0.025, 0.5, 1, 2, 3, 4]: plt.axvline(np.log10(j), linestyle = '--') plt.xlabel('Frequency [Hz] (power of 10)') plt.ylabel('Phase [radian] (power of 10)') plt.legend() # title, centered above both subplots # make more room in between subplots for the ylabel of right plot plt.subplots_adjust(wspace=0.3) """ plt.show() print str(i+1) + '/' + str(len(ls_first)) print ls_first[i] print '------------------' wait = raw_input(id_name) print '***************************' except Exception, error: print '##################' print error print '##################'
def computePSD(sp,net,sta,loc,chan,dateval): #Here we compute the PSD lenfft = 5000 lenol = 2500 #Here are the different period bands. These could be done as a dicitionary #if Adam B. wants to clean this up using a dicitionary that is fine with me permin1 = 4 permax1 = 8 permin2 = 18 permax2 = 22 permin3 = 90 permax3 = 110 permin4 = 200 permax4 = 500 try: #Get the response and compute amplitude response paz=getPAZ2(sp,net,sta,loc,chan,dateval) respval = pazToFreqResp(paz['poles'],paz['zeros'],paz['sensitivity']*paz['gain'], \ t_samp = 1, nfft = lenfft,freq=False)[1:] respval = numpy.absolute(respval*numpy.conjugate(respval)) #Get the data to compute the PSD if net in set(['IW','NE','US']): locStr = '/xs1' else: locStr = '/xs0' readDataString = locStr + '/seed/' + net + '_' + sta + '/' + str(dateval.year) + \ '/' + str(dateval.year) + '_' + str(dateval.julday).zfill(3) + '_' + net + \ '_' + sta + '/' + loc + '_' + chan + '*.seed' datafiles = glob.glob(readDataString) st = Stream() for datafile in datafiles: st += read(datafile) st.merge(method=-1) #Compute the PSD cpval,fre = psd(st[0].data,NFFT=lenfft,Fs=1,noverlap=lenol,scale_by_freq=True) per = 1/fre[1:] cpval = 10*numpy.log10(((2*pi*fre[1:])**2)*cpval[1:]/respval) perminind1 = numpy.abs(per-permin1).argmin() permaxind1 = numpy.abs(per-permax1).argmin() perminind2 = numpy.abs(per-permin2).argmin() permaxind2 = numpy.abs(per-permax2).argmin() perminind3 = numpy.abs(per-permin3).argmin() permaxind3 = numpy.abs(per-permax3).argmin() perminind4 = numpy.abs(per-permin4).argmin() permaxind4 = numpy.abs(per-permax4).argmin() perNLNM,NLNM = get_NLNM() perNLNMminind1 = numpy.abs(perNLNM-permin1).argmin() perNLNMmaxind1 = numpy.abs(perNLNM-permax1).argmin() perNLNMminind2 = numpy.abs(perNLNM-permin2).argmin() perNLNMmaxind2 = numpy.abs(perNLNM-permax2).argmin() perNLNMminind3 = numpy.abs(perNLNM-permin3).argmin() perNLNMmaxind3 = numpy.abs(perNLNM-permax3).argmin() perNLNMminind4 = numpy.abs(perNLNM-permin4).argmin() perNLNMmaxind4 = numpy.abs(perNLNM-permax4).argmin() cpval1 = round(numpy.average(cpval[permaxind1:perminind1]) - \ numpy.average(NLNM[perNLNMmaxind1:perNLNMminind1]),2) cpval2 = round(numpy.average(cpval[permaxind2:perminind2]) - \ numpy.average(NLNM[perNLNMmaxind2:perNLNMminind2]),2) cpval3 = round(numpy.average(cpval[permaxind3:perminind3]) - \ numpy.average(NLNM[perNLNMmaxind3:perNLNMminind3]),2) cpval4 = round(numpy.average(cpval[permaxind4:perminind4]) - \ numpy.average(NLNM[perNLNMmaxind4:perNLNMminind4]),2) except: cpval1 = 0 cpval2 = 0 cpval3 = 0 cpval4 = 0 return cpval1, cpval2, cpval3,cpval4
def retrieve_timeseries(params,channel,segment): """@retrieves timeseries for given channel and segment. @param params seismon params dictionary @param channel seismon channel structure @param segment [start,end] gps """ gpsStart = segment[0] gpsEnd = segment[1] # set the times duration = np.ceil(gpsEnd-gpsStart) dataFull = [] if params["ifo"] == "IRIS": import obspy.iris channelSplit = channel.station.split(":") #starttime = lal.gpstime.gps_to_utc(params["gpsStart"]) #endtime = lal.gpstime.gps_to_utc(params["gpsEnd"]) #starttime = obspy.core.UTCDateTime(starttime) #endtime = obspy.core.UTCDateTime(endtime) starttime = astropy.time.Time(gpsStart, format='gps') endtime = astropy.time.Time(gpsEnd, format='gps') starttime = obspy.core.UTCDateTime(starttime.utc.iso) endtime = obspy.core.UTCDateTime(endtime.utc.iso) client = params["client"] #client = obspy.fdsn.client.Client("IRIS") try: st = client.get_waveforms(channelSplit[0], channelSplit[1], channelSplit[2], channelSplit[3],\ starttime,endtime) except: print "data read from IRIS failed... continuing\n" return dataFull data = np.array(st[0].data) data = data.astype(float) dataFull = gwpy.timeseries.TimeSeries(data, times=None, epoch=gpsStart, channel=channel.station, unit=None,sample_rate=channel.samplef, name=channel.station) elif params["ifo"] == "LUNAR": import obspy traces = [] for frame in params["frame"]: st = obspy.read(frame) for trace in st: trace_station = "%s:%s:%s:%s"%(trace.stats["network"],trace.stats["station"],trace.stats["location"],trace.stats["channel"]) if trace_station == channel.station: traces.append(trace) st = obspy.core.stream.Stream(traces=traces) starttime = UnixToUTCDateTime(gpsStart) endtime = UnixToUTCDateTime(gpsEnd) st = st.slice(starttime, endtime) data = st[0].data data = data.astype(float) #data = RunningMedian(data,701,2) sample_rate = st[0].stats.sampling_rate dataFull = gwpy.timeseries.TimeSeries(data, times=None, epoch=gpsStart, channel=channel.station, unit=None,sample_rate=sample_rate, name=channel.station) dataFull.resample(channel.samplef) elif params["ifo"] == "CZKHC": stationSplit = channel.station.split(":") stationID = stationSplit[0] stationType = stationSplit[1] tt = [] data = [] import obspy for frame in params["frame"]: frameSplit = frame.split("/") frameName = frameSplit[-1] datalines = [line.strip() for line in open(frame)] #datalines = datalines[13:] datalines = datalines[1:] dataStart = False for dataline in datalines: year = int(dataline[0:4]) month = int(dataline[5:7]) day = int(dataline[8:10]) hour = int(dataline[11:13]) minute = int(dataline[14:16]) second = int(dataline[17:19]) subsecond = int(dataline[20:26]) thisDate = datetime(year, month, day, hour, minute, second, subsecond) #thistime = lal.gpstime.utc_to_gps(thisDate) td = thisDate - datetime(1970, 1, 1) thistime = td.microseconds * 1e-6 + td.seconds + td.days * 24 * 3600 tt.append(thistime) counts = int(dataline[26:]) data.append(counts) if thistime > gpsEnd: break tt, data = zip(*sorted(zip(tt, data))) tt = np.array(tt) data = np.array(data) indexes = np.intersect1d(np.where(tt >= gpsStart)[0],np.where(tt <= gpsEnd)[0]) tt = tt[indexes] data = data[indexes] if len(data) == 0: return [] sample_rate = channel.samplef dataFull = gwpy.timeseries.TimeSeries(data, times=None, epoch=gpsStart, channel=channel.station, unit=None,sample_rate=sample_rate, name=channel.station) dataFull.resample(channel.samplef) elif params["ifo"] == "SR": stationPeriod = channel.station.replace(":",".") stationSplit = channel.station.split(":") stationPeriod = "%s.%s.%s.%s"%(stationSplit[1],stationSplit[0],stationSplit[2],stationSplit[3]) tt = [] data = [] import obspy for frame in params["frame"]: index = frame.find(stationPeriod) if index < 0: continue frameSplit = frame.split("/") frameName = frameSplit[-1] frameSplit = frameName.split("_") frameDate = frameSplit[0] #thisDate = datetime.strptime(frameDate, '%Y.%j.%H.%M.%S.%f') #thistime = lal.gpstime.utc_to_gps(thisDate) #td = thisDate - datetime(1970, 1, 1) #thistime = td.microseconds * 1e-6 + td.seconds + td.days * 24 * 3600 #if thistime > gpsEnd: # continue #if thistime + 86400 < gpsStart: # continue datalines = [line.strip() for line in open(frame)] #datalines = datalines[13:] #datalines = datalines[1:] dataStart = False thistime = [] for dataline in datalines: if dataline[0:4] == "TIME": thistime = [] continue if not thistime: year = int(dataline[0:4]) month = int(dataline[5:7]) day = int(dataline[8:10]) hour = int(dataline[11:13]) minute = int(dataline[14:16]) second = int(dataline[17:19]) subsecond = int(dataline[20:26]) thisDate = datetime(year, month, day, hour, minute, second, subsecond) #thistime = lal.gpstime.utc_to_gps(thisDate) td = thisDate - datetime(1970, 1, 1) thistime = td.microseconds * 1e-6 + td.seconds + td.days * 24 * 3600 else: thistime = thistime + 1.0/channel.samplef if thistime > gpsEnd: break if thistime < gpsStart: continue tt.append(thistime) counts = float(dataline[26:]) data.append(counts) if len(data) == 0: return [] tt, data = zip(*sorted(zip(tt, data))) tt = np.array(tt) data = np.array(data) indexes = np.intersect1d(np.where(tt >= gpsStart)[0],np.where(tt <= gpsEnd)[0]) tt = tt[indexes] data = data[indexes] if len(data) == 0: return [] sample_rate = channel.samplef from obspy.signal import seisSim, pazToFreqResp paz_remove = {'gain': 6.76557e9, 'poles': [(-4.65+3.46j), (-4.65-3.46j), (-.118),(-40.9), (-100.0),(-.15), (-264.0), (-16.7+3.4j), (-16.7-3.4j), (-63.3),(-63.3)], 'zeros': [0j,0j,0j,0j,-.126,-50.1], 'sensitivity': 1} #'sensitivity': 2.00000e12} #'sensitivity': 1} # Translated from PITSA: spr_resg.c delta = 1.0 / sample_rate # ndat = len(data) nfft = ndat freq_response, freqs = pazToFreqResp(paz_remove['poles'], paz_remove['zeros'], paz_remove['gain'], delta, nfft, freq=True) from obspy.signal import seisSim #data = seisSim(data, sample_rate, paz_remove=paz_remove) dataFull = gwpy.timeseries.TimeSeries(data, times=None, epoch=gpsStart, channel=channel.station, unit=None,sample_rate=sample_rate, name=channel.station) dataFull.resample(channel.samplef) elif params["ifo"] == "Gravimeter": stationSplit = channel.station.split(":") stationID = stationSplit[0] stationType = stationSplit[1] tt = [] data = [] import obspy for frame in params["frame"]: frameSplit = frame.split("/") frameName = frameSplit[-1] frameNameSplit = frameName.split("+") frameNameSplit = frameNameSplit[1] frameID = frameNameSplit[:2] frameDate = frameNameSplit[2:8] if not stationID.lower() == frameID.lower(): continue year = int(frameDate[0:2]) if year < 20: year = year + 2000 else: year = year + 1900 month = int(frameDate[2:4]) day = int(frameDate[4:6]) if day == 0: day = 1 hour = 0 minute = 0 second = 0 thisDate = datetime(year, month, day, hour, minute, second) thistime = lal.gpstime.utc_to_gps(thisDate) if thistime.gpsSeconds > gpsEnd: continue if thistime.gpsSeconds + 31*86400 < gpsStart: continue datalines = [line.strip() for line in open(frame)] #datalines = datalines[13:] #datalines = datalines[1:] dataStart = False for dataline in datalines: if len(dataline) == 0: continue if dataline[0:5] == "77777": dataStart = True continue if dataline[0:5] == "88888": dataStart = True continue if dataline[0] == "#": continue if dataline[0:5] == "99999": dataStart = False break if dataStart == False: continue year = int(dataline[0:4]) month = int(dataline[4:6]) day = int(dataline[6:8]) try: hour = int(dataline[9:11]) except: hour = 0 try: minute = int(dataline[11:13]) except: minute = 0 try: second = int(dataline[13:15]) except: second = 0 thisDate = datetime(year, month, day, hour, minute, second) thistime = lal.gpstime.utc_to_gps(thisDate) if thistime.gpsSeconds > gpsEnd: break if thistime.gpsSeconds + 31*86400 < gpsStart: break datalineSplit = dataline[15:].split(" ") datalineSplit = filter(None, datalineSplit) if datalineSplit[0][0] == "*": gravity = 0 pressure = 0 elif len(datalineSplit) == 2: gravity = float(datalineSplit[0]) pressure = float(datalineSplit[1]) elif len(datalineSplit) == 1: datalineSplit2 = datalineSplit[0].split("-") datalineSplit2 = filter(None, datalineSplit2) if len(datalineSplit2) == 2: gravity = float(datalineSplit2[0]) pressure = -float(datalineSplit2[1]) else: datalineSplit = datalineSplit[0] gravity = float(datalineSplit[0:10]) try: pressure = float(datalineSplit[10:]) except: pressure = 0 else: continue if gravity == 99.0 or gravity > 9999.9: gravity = 0 pressure = 0 tt.append(thistime.gpsSeconds) if stationType == "PRESSURE": data.append(pressure) elif stationType == "GRAVITY": data.append(gravity) if len(data) == 0: return [] tt, data = zip(*sorted(zip(tt, data))) tt = np.array(tt) data = np.array(data) indexes = np.intersect1d(np.where(tt >= gpsStart)[0],np.where(tt <= gpsEnd)[0]) tt = tt[indexes] data = data[indexes] if len(data) == 0: return [] sample_rate = channel.samplef dataFull = gwpy.timeseries.TimeSeries(data, times=None, epoch=gpsStart, channel=channel.station, unit=None,sample_rate=sample_rate, name=channel.station) dataFull.resample(channel.samplef) else: #for frame in params["frame"]: # print frame.path # frame_data,data_start,_,dt,_,_ = Fr.frgetvect1d(frame.path,channel.station) #print params["frame"] #dataFull = gwpy.timeseries.TimeSeries.read(params["frame"], channel.station, epoch=gpsStart, duration=duration) #print "done" # make timeseries #dataFull = gwpy.timeseries.TimeSeries.read(params["frame"], channel.station, start=gpsStart, end=gpsEnd, gap='pad', pad = 0.0) try: dataFull = gwpy.timeseries.TimeSeries.read(params["frame"], channel.station, start=gpsStart, end=gpsEnd, gap='pad', pad = 0.0) except: print "data read from frames failed... continuing\n" return dataFull return dataFull
def plot_xml_response(input_dics): """ plot the transfer function of stationXML file(s) :param input_dics: :return: """ plt.rc('font', family='serif') print('[INFO] plotting StationXML file/files in: %s' % \ input_dics['datapath']) if not os.path.isdir('./stationxml_plots'): print('[INFO] creating stationxml_plots directory...') os.mkdir('./stationxml_plots') # assign the input_dics parameters to the running parameters: stxml_dir = input_dics['datapath'] plotxml_datetime = input_dics['plotxml_date'] min_freq = input_dics['plotxml_min_freq'] output = input_dics['plotxml_output'] if 'dis' in output.lower(): output = 'DISP' elif 'vel' in output.lower(): output = 'VEL' elif 'acc' in output.lower(): output = 'ACC' else: output = output.upper() start_stage = input_dics['plotxml_start_stage'] end_stage_input = input_dics['plotxml_end_stage'] percentage = input_dics['plotxml_percentage'] / 100. threshold = input_dics['plotxml_phase_threshold'] plot_response = input_dics['plotxml_response'] plotstage12 = input_dics['plotxml_plotstage12'] plotpaz = input_dics['plotxml_paz'] plotallstages = input_dics['plotxml_allstages'] plot_map_compare = input_dics['plotxml_map_compare'] if os.path.isfile(stxml_dir): addxml_all = glob.glob(os.path.join(stxml_dir)) elif os.path.isdir(stxml_dir): addxml_all = glob.glob(os.path.join(stxml_dir, 'STXML.*')) else: try: addxml_all = glob.glob(os.path.join(stxml_dir)) except Exception as error: print('[ERROR] %s' % error) sys.exit('[ERROR] wrong address: %s' % stxml_dir) addxml_all.sort() sta_lat = [] sta_lon = [] latlon_color = [] report_fio = open(os.path.join('stationxml_plots', 'report_stationxml'), 'wt') report_fio.writelines('channel_id\t\t\t\t%(phase_diff)\t\t' 'abs(max_diff)\tlat\t\t\tlon\t\t\tdatetime\t' 'decimation delay\tdecimation corr\n') report_fio.close() add_counter = 0 for addxml in addxml_all: end_stage = end_stage_input add_counter += 1 print(40 * '-') print('%s/%s' % (add_counter, len(addxml_all))) try: xml_inv = read_inventory(addxml, format='stationXML') print("[STATIONXML] %s" % addxml) # we only take into account the first channel... cha_name = xml_inv.get_contents()['channels'][0] if plotxml_datetime: cha_date = plotxml_datetime else: cha_date = xml_inv.networks[0][0][-1].start_date print('[INFO] plotxml_date has not been set, the start_date ' \ 'of the last channel in stationXML file will be used ' \ 'instead: %s' % cha_date) xml_response = xml_inv.get_response(cha_name, cha_date + 0.1) if xml_inv[0][0][0].sample_rate: sampling_rate = xml_inv[0][0][0].sample_rate else: for stage in xml_response.response_stages[::-1]: if (stage.decimation_input_sample_rate is not None) and\ (stage.decimation_factor is not None): sampling_rate = (stage.decimation_input_sample_rate / stage.decimation_factor) break t_samp = 1.0 / sampling_rate nyquist = sampling_rate / 2.0 nfft = int(sampling_rate / min_freq) end_stage = min(len(xml_response.response_stages), end_stage) if plotallstages: plot_xml_plotallstages(xml_response, t_samp, nyquist, nfft, min_freq, output, start_stage, end_stage, cha_name) try: cpx_response, freq = xml_response.get_evalresp_response( t_samp=t_samp, nfft=nfft, output=output, start_stage=start_stage, end_stage=end_stage) cpx_12, freq = xml_response.get_evalresp_response( t_samp=t_samp, nfft=nfft, output=output, start_stage=1, end_stage=2) except Exception as error: print('[WARNING] %s' % error) continue paz, decimation_delay, decimation_correction = \ convert_xml_paz(xml_response, output, cha_name, cha_date) if not paz: continue h, f = pazToFreqResp(paz['poles'], paz['zeros'], paz['gain'], 1. / sampling_rate, nfft, freq=True) phase_resp = np.angle(cpx_response) phase_12 = np.angle(cpx_12) if plot_response: plt.figure(figsize=(20, 10)) plt.suptitle(cha_name, size=24, weight='bold') if plotpaz or plotstage12: plt.subplot(2, 2, 1) else: plt.subplot(2, 1, 1) plt.loglog(freq, abs(cpx_response), color='blue', lw=3, label='full-resp') if plotstage12: plt.loglog(freq, abs(cpx_12), ls='--', color='black', lw=3, label='Stage1,2') if plotpaz: plt.loglog(f, abs(h) * paz['sensitivity'], color='red', lw=3, label='PAZ') plt.axvline(nyquist, ls="--", color='black', lw=3) plt.ylabel('Amplitude', size=24, weight='bold') plt.xticks(size=18, weight='bold') plt.yticks(size=18, weight='bold') plt.xlim(xmin=min_freq, xmax=nyquist + 5) plt.ylim(ymax=max(1.2 * abs(cpx_response))) plt.legend(loc=0, prop={'size': 18, 'weight': 'bold'}) plt.grid() if plotpaz or plotstage12: plt.subplot(2, 2, 3) else: plt.subplot(2, 1, 2) plt.semilogx(freq, phase_resp, color='blue', lw=3, label='full-resp') if plotstage12: plt.semilogx(freq, phase_12, ls='--', color='black', lw=3, label='Stage1,2') if plotpaz: plt.semilogx(f, np.angle(h), color='red', lw=3, label='PAZ') plt.axvline(nyquist, ls="--", color='black', lw=3) plt.xlabel('Frequency [Hz]', size=24, weight='bold') plt.ylabel('Phase [rad]', size=24, weight='bold') plt.xticks(size=18, weight='bold') plt.yticks(size=18, weight='bold') plt.xlim(xmin=min_freq, xmax=nyquist + 5) plt.legend(loc=0, prop={'size': 18, 'weight': 'bold'}) plt.grid() if plotstage12 or plotpaz: ax_222 = plt.subplot(2, 2, 2) y_label = 'Amplitude ratio' if plotstage12: plt.loglog(freq, abs(abs(cpx_response) / abs(cpx_12)), '--', color='black', lw=3, label='|full-resp|/|Stage1,2|') y_label = '|full-resp|/|Stage1,2|' amp_ratio = 1 if plotpaz: amp_ratio = abs( abs(cpx_response) / (abs(h) * paz['sensitivity'])) plt.loglog(f, amp_ratio, color='red', lw=3, label='|full-resp|/|PAZ|') y_label = '|full-resp|/|PAZ|' plt.axvline(nyquist, ls="--", color='black', lw=3) plt.axvline(percentage * nyquist, ls="--", color='black', lw=3) plt.ylabel(y_label, size=24, weight='bold') plt.xticks(size=18, weight='bold') plt.yticks(size=18, weight='bold') plt.xlim(xmin=min_freq, xmax=nyquist + 5) plt.ylim( ymax=1.2 * max(amp_ratio[np.logical_not(np.isnan(amp_ratio))])) plt.grid() ax_224 = plt.subplot(2, 2, 4) y_label = 'Phase difference [rad]' if plotstage12: plt.semilogx(freq, abs(phase_resp - phase_12), color='black', ls='--', lw=3, label='|full-resp - Stage1,2|') y_label = '|full-resp - Stage1,2| [rad]' if plotpaz: plt.semilogx(freq, abs(phase_resp - np.angle(h)), color='red', lw=3, label='|full-resp - PAZ|') y_label = '|full-resp - PAZ|' plt.axvline(nyquist, ls="--", color='black', lw=3) plt.axvline(percentage * nyquist, ls="--", color='black', lw=3) plt.xlabel('Frequency [Hz]', size=24, weight='bold') plt.ylabel(y_label, size=24, weight='bold') plt.xticks(size=18, weight='bold') plt.yticks(size=18, weight='bold') plt.xlim(xmin=min_freq, xmax=nyquist + 5) plt.grid() plt.savefig(os.path.join('stationxml_plots', cha_name + '.png')) plt.close() # compare = abs(phase[:int(0.8*len(phase))] - # np.angle(h[:int(0.8*len(phase))])) # if len(compare[compare>0.1]) > 0: # lat_red.append(xml_inv.get_coordinates(cha_name)['latitude']) # lon_red.append(xml_inv.get_coordinates(cha_name)['longitude']) # print cha_name # print paz # else: # lat_blue.append(xml_inv.get_coordinates(cha_name)['latitude']) # lon_blue.append(xml_inv.get_coordinates(cha_name)['longitude']) phase_resp_check = phase_resp[:int(percentage * len(phase_resp))] phase_h_check = np.angle(h)[:int(percentage * len(np.angle(h)))] if not len(phase_resp_check) == len(phase_h_check): sys.exit('[ERROR] lengths of phase responses do not match: ' '%s (StationXML) != %s (PAZ)' % (len(phase_resp_check), len(phase_h_check))) compare = abs(phase_resp_check - phase_h_check) percent_compare = \ float(len(compare[compare >= 0.05]))/len(compare)*100 latlondep = get_coordinates(xml_inv.networks[0], cha_name, cha_date + 0.1) sta_lat.append(latlondep['latitude']) sta_lon.append(latlondep['longitude']) d_c = np.sum(decimation_delay) - np.sum(decimation_correction) if not d_c == 0: latlon_color.append(0.) else: latlon_color.append(percent_compare) if percent_compare >= threshold: plot_xml_plotallstages(xml_response, t_samp, nyquist, nfft, min_freq, output, start_stage, end_stage, cha_name) report_fio = open( os.path.join('stationxml_plots', 'report_stationxml'), 'at') report_fio.writelines( '%s\t\t\t%6.2f\t\t\t%6.2f\t\t\t%6.2f\t\t%7.2f\t\t%s\t%s\t%s\n' % (cha_name, round(percent_compare, 2), round(max(abs(compare)), 2), round( sta_lat[-1], 2), round(sta_lon[-1], 2), cha_date, np.sum(decimation_delay), np.sum(decimation_correction))) report_fio.close() except Exception as error: print('[Exception] %s' % error) if plot_map_compare: plt.figure() m = Basemap(projection='robin', lon_0=input_dics['plot_lon0'], lat_0=0) m.fillcontinents() m.drawparallels(np.arange(-90., 120., 30.)) m.drawmeridians(np.arange(0., 420., 60.)) m.drawmapboundary() x, y = m(sta_lon, sta_lat) m.scatter(x, y, 100, c=latlon_color, marker="v", edgecolor='none', zorder=10, cmap='rainbow') plt.colorbar(orientation='horizontal') plt.savefig(os.path.join('stationxml_plots', 'compare_plots.png')) plt.show() raw_input_built('Press Enter...') sys.exit('[EXIT] obspyDMT finished normally...')
'poles': [-4.21000 + 4.66000j, - 4.21000 - 4.66000j, - 2.105000 + 0.00000j], 'zeros': [0.0 + 0.0j] * 3, # add or remove zeros here 'gain' : 0.4 } # Read in the data tr = read("loc_RJOB20050831023349.z")[0] # Do the instrument correction data_corr = seisSim(tr.data, tr.stats.sampling_rate, le3d, inst_sim=PAZ_WOOD_ANDERSON, water_level=60.0) # Just for visualization, calculate transferfuction in frequency domain trans, freq = pazToFreqResp(le3d['poles'], le3d['zeros'], le3d['gain'], 1./tr.stats.sampling_rate, 2**12, freq=True) # # The plotting part # time = np.arange(0,tr.stats.npts)/tr.stats.sampling_rate plt.figure() plt.subplot(211) plt.plot(time, tr.data, label="Original Data") plt.legend() plt.subplot(212) plt.plot(time, data_corr, label="Wood Anderson Simulated Data") plt.legend() plt.xlabel("Time [s]") plt.suptitle("Original and Corrected Data")