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...')
def plot_sta_ev_ray(input_dics, events): """ plot stations, events and ray paths on a map using basemap. :param input_dics: :param events: :return: """ plt.figure(figsize=(20., 10.)) plt_stations = input_dics['plot_sta'] plt_availability = input_dics['plot_availability'] plt_events = input_dics['plot_ev'] plt_ray_path = input_dics['plot_ray'] if input_dics['evlatmin'] is None: evlatmin = -90 evlatmax = +90 evlonmin = -180 evlonmax = +180 glob_map = True else: evlatmin = input_dics['evlatmin'] evlatmax = input_dics['evlatmax'] evlonmin = input_dics['evlonmin'] evlonmax = input_dics['evlonmax'] glob_map = False if plt_ray_path: # # hammer, kav7, cyl, mbtfpq, moll m = Basemap(projection='moll', lon_0=input_dics['plot_lon0']) parallels = np.arange(-90, 90, 30.) m.drawparallels(parallels, fontsize=24) meridians = np.arange(-180., 180., 60.) m.drawmeridians(meridians, fontsize=24) width_beach = 10e5 width_station = 50 elif not glob_map: m = Basemap(projection='cyl', llcrnrlat=evlatmin, urcrnrlat=evlatmax, llcrnrlon=evlonmin, urcrnrlon=evlonmax) parallels = np.arange(-90, 90, 5.) m.drawparallels(parallels, fontsize=12) meridians = np.arange(-180., 180., 5.) m.drawmeridians(meridians, fontsize=12) width_beach = 5 width_station = 10 elif glob_map: m = Basemap(projection='moll', lon_0=input_dics['plot_lon0']) parallels = np.arange(-90, 90, 30.) m.drawparallels(parallels, fontsize=24) meridians = np.arange(-180., 180., 60.) m.drawmeridians(meridians, fontsize=24) width_beach = 5e5 width_station = 50 else: sys.exit('[ERROR] can not continue, error:\n%s' % input_dics) raw_input_resp = raw_input_built('choose the map style:\n' '1. bluemarble (PIL should be installed)\n' '2. etopo (PIL should be installed)\n' '3. shadedrelief (PIL should be installed)\n' '4. simple\n') if int(raw_input_resp) == 1: m.bluemarble(scale=0.5) elif int(raw_input_resp) == 2: m.etopo(scale=0.5) elif int(raw_input_resp) == 3: m.shadedrelief(scale=0.1) else: m.fillcontinents() for ei in range(len(events)): if plt_events: if input_dics['plot_focal']: if not events[ei]['focal_mechanism']: print('[ERROR] moment tensor does not exist!') continue x, y = m(events[ei]['longitude'], events[ei]['latitude']) focmecs = [float(events[ei]['focal_mechanism'][0]), float(events[ei]['focal_mechanism'][1]), float(events[ei]['focal_mechanism'][2]), float(events[ei]['focal_mechanism'][3]), float(events[ei]['focal_mechanism'][4]), float(events[ei]['focal_mechanism'][5])] try: ax = plt.gca() b = Beach(focmecs, xy=(x, y), facecolor='blue', width=width_beach, linewidth=1, alpha=0.85) b.set_zorder(10) ax.add_collection(b) except Exception as error: print("[WARNING: %s -- %s]" % (error, focmecs)) continue else: x, y = m(events[ei]['longitude'], events[ei]['latitude']) magnitude = float(events[ei]['magnitude']) m.scatter(x, y, color="blue", s=10*magnitude, edgecolors='none', marker="o", zorder=5, alpha=0.65) if plt_stations or plt_availability or plt_ray_path: target_path = locate(input_dics['datapath'], events[ei]['event_id']) if len(target_path) == 0: continue if len(target_path) > 1: print("[LOCAL] more than one path was found for the event:") print(target_path) print("[INFO] use the first one:") target_path = target_path[0] print(target_path) else: print("[LOCAL] Path:") target_path = target_path[0] print(target_path) update_sta_ev_file(target_path, events[ei]) if not input_dics['plot_availability']: sta_ev_arr = np.loadtxt(os.path.join(target_path, 'info', 'station_event'), delimiter=',', dtype=bytes, ndmin=2).astype(np.str) else: sta_ev_arr = np.loadtxt(os.path.join(target_path, 'info', 'availability.txt'), delimiter=',', dtype=bytes, ndmin=2).astype(np.str) sta_ev_arr = sta_ev_arr.astype(np.object) if events[ei]['magnitude'] > 0: del_index = [] for sti in range(len(sta_ev_arr)): if not plot_filter_station(input_dics, sta_ev_arr[sti]): del_index.append(sti) dist, azi, bazi = gps2DistAzimuth( events[ei]['latitude'], events[ei]['longitude'], float(sta_ev_arr[sti, 4]), float(sta_ev_arr[sti, 5])) epi_dist = dist/111.194/1000. if input_dics['min_azi'] or input_dics['max_azi'] or \ input_dics['min_epi'] or input_dics['max_epi']: if input_dics['min_epi']: if epi_dist < input_dics['min_epi']: del_index.append(sti) if input_dics['max_epi']: if epi_dist > input_dics['max_epi']: del_index.append(sti) if input_dics['min_azi']: if azi < input_dics['min_azi']: del_index.append(sti) if input_dics['max_azi']: if azi > input_dics['max_azi']: del_index.append(sti) del_index = list(set(del_index)) del_index.sort(reverse=True) for di in del_index: sta_ev_arr = np.delete(sta_ev_arr, (di), axis=0) if plt_stations or plt_availability: if len(sta_ev_arr) > 0: x, y = m(sta_ev_arr[:, 5], sta_ev_arr[:, 4]) m.scatter(x, y, color='red', s=width_station, edgecolors='none', marker='v', zorder=4, alpha=0.9) if plt_ray_path: for si in range(len(sta_ev_arr)): gcline = m.drawgreatcircle(float(events[ei]['longitude']), float(events[ei]['latitude']), float(sta_ev_arr[si][5]), float(sta_ev_arr[si][4]), color='k', alpha=0.0) gcx, gcy = gcline[0].get_data() gcx_diff = gcx[0:-1] - gcx[1:] gcy_diff = gcy[0:-1] - gcy[1:] if np.max(abs(gcx_diff))/abs(gcx_diff[0]) > 300: gcx_max_arg = abs(gcx_diff).argmax() plt.plot(gcx[0:gcx_max_arg], gcy[0:gcx_max_arg], color='k', alpha=0.1) plt.plot(gcx[gcx_max_arg+1:], gcy[gcx_max_arg+1:], color='k', alpha=0.1) elif np.max(abs(gcy_diff))/abs(gcy_diff[0]) > 400: gcy_max_arg = abs(gcy_diff).argmax() plt.plot(gcy[0:gcy_max_arg], gcy[0:gcy_max_arg], color='k', alpha=0.1) plt.plot(gcy[gcy_max_arg+1:], gcy[gcy_max_arg+1:], color='k', alpha=0.1) else: m.drawgreatcircle(float(events[ei]['longitude']), float(events[ei]['latitude']), float(sta_ev_arr[si][5]), float(sta_ev_arr[si][4]), color='k', alpha=0.1) plt.savefig(os.path.join(input_dics['plot_save'], 'event_station.%s' % input_dics['plot_format'])) plt.show()
def plot_seismicity(input_dics, events): """ create a seismicity map with some basic statistical analysis on the results :param input_dics: :param events: :return: """ print('\n==============') print('Seismicity map') print('==============\n') # plt.rc('font', family='serif') if not len(events) > 0: print("[WARNING] no event passed the given criteria!") print("[WARNING] can not create any seismicity map.") return if input_dics['evlatmin'] is None: input_dics['evlatmin'] = -90 input_dics['evlatmax'] = +90 input_dics['evlonmin'] = -180 input_dics['evlonmax'] = +180 map_proj = 'cyl' else: map_proj = 'cyl' # set-up the map m = Basemap(projection=map_proj, llcrnrlat=input_dics['evlatmin'], urcrnrlat=input_dics['evlatmax'], llcrnrlon=input_dics['evlonmin'], urcrnrlon=input_dics['evlonmax'], lon_0=input_dics['plot_lon0'], resolution='l') parallels = np.arange(-90, 90, 30.) m.drawparallels(parallels, fontsize=24) meridians = np.arange(-180., 180., 60.) m.drawmeridians(meridians, fontsize=24) raw_input_resp = raw_input_built('choose the map style:\n' '1. bluemarble (PIL should be installed)\n' '2. etopo (PIL should be installed)\n' '3. shadedrelief (PIL should be installed)\n' '4. simple\n') if int(raw_input_resp) == 1: m.bluemarble(scale=0.5) elif int(raw_input_resp) == 2: m.etopo(scale=0.5) elif int(raw_input_resp) == 3: m.shadedrelief(scale=0.1) else: m.fillcontinents() # defining labels x_ev, y_ev = m(-360, 0) m.scatter(x_ev, y_ev, 20, color='red', marker="o", edgecolor="black", zorder=10, label='0-70km') m.scatter(x_ev, y_ev, 20, color='green', marker="o", edgecolor="black", zorder=10, label='70-300km') m.scatter(x_ev, y_ev, 20, color='blue', marker="o", edgecolor="black", zorder=10, label='300< km') m.scatter(x_ev, y_ev, 10, color='white', marker="o", edgecolor="black", zorder=10, label='< 4.0') m.scatter(x_ev, y_ev, 40, color='white', marker="o", edgecolor="black", zorder=10, label='4.0-5.0') m.scatter(x_ev, y_ev, 70, color='white', marker="o", edgecolor="black", zorder=10, label='5.0-6.0') m.scatter(x_ev, y_ev, 100, color='white', marker="o", edgecolor="black", zorder=10, label='6.0<=') ev_dp_all = [] ev_mag_all = [] ev_info_ar = np.array([]) plot_focal_mechanism = False for ev in events: x_ev, y_ev = m(float(ev['longitude']), float(ev['latitude'])) ev_dp_all.append(abs(float(ev['depth']))) ev_mag_all.append(abs(float(ev['magnitude']))) if abs(float(ev['depth'])) < 70.0: color = 'red' elif 70.0 <= abs(float(ev['depth'])) < 300.0: color = 'green' elif 300.0 <= abs(float(ev['depth'])): color = 'blue' if float(ev['magnitude']) < 4.0: size = 10 elif 4.0 <= float(ev['magnitude']) < 5.0: size = 40 elif 5.0 <= float(ev['magnitude']) < 6.0: size = 70 elif 6.0 <= float(ev['magnitude']): size = 100 if ev['focal_mechanism']: plot_focal_mechanism = True f1 = ev['focal_mechanism'][0] f2 = ev['focal_mechanism'][1] f3 = ev['focal_mechanism'][2] f4 = ev['focal_mechanism'][3] f5 = ev['focal_mechanism'][4] f6 = ev['focal_mechanism'][5] else: f1 = False f2 = False f3 = False f4 = False f5 = False f6 = False if np.size(ev_info_ar) < 1: ev_info_ar = np.append(ev_info_ar, [float(ev['depth']), float(x_ev), float(y_ev), size, color, f1, f2, f3, f4, f5, f6]) else: ev_info_ar = np.vstack((ev_info_ar, [float(ev['depth']), float(x_ev), float(y_ev), size, color, f1, f2, f3, f4, f5, f6])) if np.shape(ev_info_ar)[0] == np.size(ev_info_ar): ev_info_ar = np.reshape(ev_info_ar, (1, 11)) else: ev_info_ar = sorted(ev_info_ar, key=lambda ev_info_iter: float(ev_info_iter[0])) for ev in ev_info_ar: m.scatter(float(ev[1]), float(ev[2]), float(ev[3]), color=ev[4], marker="o", edgecolor='k', zorder=10) plt.legend(bbox_to_anchor=(1.01, 1), loc=2, borderaxespad=0.) if plot_focal_mechanism: plt.figure() m = Basemap(projection=map_proj, llcrnrlat=input_dics['evlatmin'], urcrnrlat=input_dics['evlatmax'], llcrnrlon=input_dics['evlonmin'], urcrnrlon=input_dics['evlonmax'], lon_0=input_dics['plot_lon0'], resolution='l') parallels = np.arange(-90, 90, 30.) m.drawparallels(parallels, fontsize=24) meridians = np.arange(-180., 180., 60.) m.drawmeridians(meridians, fontsize=24) if int(raw_input_resp) == 1: m.bluemarble(scale=0.5) elif int(raw_input_resp) == 2: m.etopo(scale=0.5) elif int(raw_input_resp) == 3: m.shadedrelief(scale=0.1) else: m.fillcontinents() for evfoc in ev_info_ar: focmec = False try: ax = plt.gca() focmec = (float(evfoc[5]), float(evfoc[6]), float(evfoc[7]), float(evfoc[8]), float(evfoc[9]), float(evfoc[10])) b = Beach(focmec, xy=(float(evfoc[1]), float(evfoc[2])), facecolor=evfoc[4], width=float(evfoc[3])/100., linewidth=1, alpha=0.85) b.set_zorder(10) ax.add_collection(b) except Exception as error: print('[EXCEPTION] focal mechanism:') print(focmec) print('[EXCEPTION] error: %s' % error) if len(events) > 0: plt.figure() hn, hbins, hpatches = \ plt.hist(ev_dp_all, input_dics['depth_bins_seismicity'], facecolor='g', edgecolor='k', lw=3, alpha=0.5, log=True) plt.xlabel('Depth', size=32, weight='bold') plt.ylabel('#Events (log)', size=32, weight='bold') plt.yscale('log') plt.ylim(ymin=0.2) plt.xticks(size=24, weight='bold') plt.yticks(size=24, weight='bold') plt.tight_layout() plt.grid(True) plt.figure() hn, hbins, hpatches = \ plt.hist(ev_mag_all, bins=np.linspace(int(float(input_dics['min_mag'])), int(float(input_dics['max_mag'])), (int(float(input_dics['max_mag'])) - int(float(input_dics['min_mag'])))*2+1), facecolor='g', edgecolor='k', lw=3, alpha=0.5, log=True) plt.xlabel('Magnitude', size=32, weight='bold') plt.ylabel('#Events (log)', size=32, weight='bold') plt.yscale('log') plt.ylim(ymin=0.2) plt.xticks(size=24, weight='bold') plt.yticks(size=24, weight='bold') plt.tight_layout() plt.grid(True) plt.show()
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...')