def rotate_traces_and_stations(datatraces, stations, event): """ Rotate traces and stations into RTZ with respect to the event. Updates channels of stations in place! Parameters --------- datatraces: list of :class:`pyrocko.trace.Trace` stations: list of :class:`pyrocko.model.Station` event: :class:`pyrocko.model.Event` Returns ------- rotated traces to RTZ """ from pyrocko import trace station2traces = utility.gather(datatraces, lambda t: t.station) trs_projected = [] for station in stations: station.set_event_relative_data(event) projections = station.guess_projections_to_rtu(out_channels=('R', 'T', 'Z')) try: traces = station2traces[station.station] except (KeyError): logger.warning('Did not find data traces for station "%s"' % stations.station) continue ntraces = len(traces) if ntraces < 3: logger.warn('Only found %i component(s) for station %s' % (ntraces, station.station)) for matrix, in_channels, out_channels in projections: proc = trace.project(traces, matrix, in_channels, out_channels) for tr in proc: logger.debug('Outtrace: \n %s' % tr.__str__()) for ch in out_channels: if ch.name == tr.channel: station.add_channel(ch) if proc: logger.debug('Updated station: \n %s' % station.__str__()) trs_projected.extend(proc) return trs_projected
def seismic_fits(problem, stage, plot_options): """ Modified from grond. Plot synthetic and data waveforms and the misfit for the selected posterior model. """ fontsize = 8 fontsize_title = 10 target_index = dict( (target, i) for (i, target) in enumerate(problem.stargets)) po = plot_options population, _, llk = stage.step.select_end_points(stage.mtrace) posterior_idxs = get_fit_indexes(llk) idx = posterior_idxs[po.post_llk] n_steps = problem.config.sampler_config.parameters.n_steps - 1 d = stage.mtrace.point(idx=n_steps, chain=idx) gcms = d['seis_like'] gcm_max = d['like'] out_point = population[idx] results = problem.assemble_seismic_results(out_point) source = problem.sources[0] logger.info('Plotting waveforms ...') target_to_result = {} all_syn_trs = [] dtraces = [] for target in problem.stargets: i = target_index[target] target_to_result[target] = results[i] all_syn_trs.append(results[i].processed_syn) dtraces.append(results[i].processed_res) skey = lambda tr: tr.channel trace_minmaxs = trace.minmax(all_syn_trs, skey) dminmaxs = trace.minmax(dtraces, skey) for tr in dtraces: if tr: dmin, dmax = dminmaxs[skey(tr)] tr.ydata /= max(abs(dmin), abs(dmax)) cg_to_targets = utility.gather( problem.stargets, lambda t: t.codes[3], filter=lambda t: t in target_to_result) cgs = cg_to_targets.keys() figs = [] for cg in cgs: targets = cg_to_targets[cg] # can keep from here ... until nframes = len(targets) nx = int(math.ceil(math.sqrt(nframes))) ny = (nframes - 1) / nx + 1 nxmax = 4 nymax = 4 nxx = (nx - 1) / nxmax + 1 nyy = (ny - 1) / nymax + 1 xs = num.arange(nx) / ((max(2, nx) - 1.0) / 2.) ys = num.arange(ny) / ((max(2, ny) - 1.0) / 2.) xs -= num.mean(xs) ys -= num.mean(ys) fxs = num.tile(xs, ny) fys = num.repeat(ys, nx) data = [] for target in targets: azi = source.azibazi_to(target)[0] dist = source.distance_to(target) x = dist * num.sin(num.deg2rad(azi)) y = dist * num.cos(num.deg2rad(azi)) data.append((x, y, dist)) gxs, gys, dists = num.array(data, dtype=num.float).T iorder = num.argsort(dists) gxs = gxs[iorder] gys = gys[iorder] targets_sorted = [targets[ii] for ii in iorder] gxs -= num.mean(gxs) gys -= num.mean(gys) gmax = max(num.max(num.abs(gys)), num.max(num.abs(gxs))) if gmax == 0.: gmax = 1. gxs /= gmax gys /= gmax dists = num.sqrt( (fxs[num.newaxis, :] - gxs[:, num.newaxis]) ** 2 + (fys[num.newaxis, :] - gys[:, num.newaxis]) ** 2) distmax = num.max(dists) availmask = num.ones(dists.shape[1], dtype=num.bool) frame_to_target = {} for itarget, target in enumerate(targets_sorted): iframe = num.argmin( num.where(availmask, dists[itarget], distmax + 1.)) availmask[iframe] = False iy, ix = num.unravel_index(iframe, (ny, nx)) frame_to_target[iy, ix] = target figures = {} for iy in xrange(ny): for ix in xrange(nx): if (iy, ix) not in frame_to_target: continue ixx = ix / nxmax iyy = iy / nymax if (iyy, ixx) not in figures: figures[iyy, ixx] = plt.figure( figsize=mpl_papersize('a4', 'landscape')) figures[iyy, ixx].subplots_adjust( left=0.03, right=1.0 - 0.03, bottom=0.03, top=1.0 - 0.06, wspace=0.2, hspace=0.2) figs.append(figures[iyy, ixx]) fig = figures[iyy, ixx] target = frame_to_target[iy, ix] amin, amax = trace_minmaxs[target.codes[3]] absmax = max(abs(amin), abs(amax)) ny_this = nymax # min(ny, nymax) nx_this = nxmax # min(nx, nxmax) i_this = (iy % ny_this) * nx_this + (ix % nx_this) + 1 axes2 = fig.add_subplot(ny_this, nx_this, i_this) space = 0.5 space_factor = 1.0 + space axes2.set_axis_off() axes2.set_ylim(-1.05 * space_factor, 1.05) axes = axes2.twinx() axes.set_axis_off() axes.set_ylim(- absmax * 1.33 * space_factor, absmax * 1.33) itarget = target_index[target] result = target_to_result[target] dtrace = dtraces[itarget] tap_color_annot = (0.35, 0.35, 0.25) tap_color_edge = (0.85, 0.85, 0.80) tap_color_fill = (0.95, 0.95, 0.90) plot_taper( axes2, result.processed_obs.get_xdata(), result.taper, fc=tap_color_fill, ec=tap_color_edge) obs_color = scolor('aluminium5') obs_color_light = light(obs_color, 0.5) syn_color = scolor('scarletred2') syn_color_light = light(syn_color, 0.5) misfit_color = scolor('scarletred2') plot_dtrace( axes2, dtrace, space, 0., 1., fc=light(misfit_color, 0.3), ec=misfit_color) plot_trace( axes, result.filtered_syn, color=syn_color_light, lw=1.0) plot_trace( axes, result.filtered_obs, color=obs_color_light, lw=0.75) plot_trace( axes, result.processed_syn, color=syn_color, lw=1.0) plot_trace( axes, result.processed_obs, color=obs_color, lw=0.75) xdata = result.filtered_obs.get_xdata() axes.set_xlim(xdata[0], xdata[-1]) tmarks = [ result.processed_obs.tmin, result.processed_obs.tmax] for tmark in tmarks: axes2.plot( [tmark, tmark], [-0.9, 0.1], color=tap_color_annot) for tmark, text, ha, va in [ (tmarks[0], '$\,$ ' + str_duration(tmarks[0] - source.time), 'right', 'bottom'), (tmarks[1], '$\Delta$ ' + str_duration(tmarks[1] - tmarks[0]), 'left', 'top')]: axes2.annotate( text, xy=(tmark, -0.9), xycoords='data', xytext=( fontsize * 0.4 * [-1, 1][ha == 'left'], fontsize * 0.2), textcoords='offset points', ha=ha, va=va, color=tap_color_annot, fontsize=fontsize) # rel_c = num.exp(gcms[itarget] - gcm_max) # sw = 0.25 # sh = 0.1 # ph = 0.01 # for (ih, rw, facecolor, edgecolor) in [ # (1, rel_c, light(misfit_color, 0.5), misfit_color)]: # bar = patches.Rectangle( # (1.0 - rw * sw, 1.0 - (ih + 1) * sh + ph), # rw * sw, # sh - 2 * ph, # facecolor=facecolor, edgecolor=edgecolor, # zorder=10, # transform=axes.transAxes, clip_on=False) # axes.add_patch(bar) scale_string = None infos = [] if scale_string: infos.append(scale_string) infos.append('.'.join(x for x in target.codes if x)) dist = source.distance_to(target) azi = source.azibazi_to(target)[0] infos.append(str_dist(dist)) infos.append(u'%.0f\u00B0' % azi) infos.append('%.3f' % gcms[itarget]) axes2.annotate( '\n'.join(infos), xy=(0., 1.), xycoords='axes fraction', xytext=(2., 2.), textcoords='offset points', ha='left', va='top', fontsize=fontsize, fontstyle='normal') for (iyy, ixx), fig in figures.iteritems(): title = '.'.join(x for x in cg if x) if len(figures) > 1: title += ' (%i/%i, %i/%i)' % (iyy + 1, nyy, ixx + 1, nxx) fig.suptitle(title, fontsize=fontsize_title) return figs
def geodetic_fits(problem, stage, plot_options): """ Plot geodetic data, synthetics and residuals. """ scattersize = 16 fontsize = 10 fontsize_title = 12 ndmax = 3 nxmax = 3 cmap = plt.cm.jet po = plot_options if po.reference is not None: problem.get_synthetics(po.reference) ref_sources = copy.deepcopy(problem.sources) target_index = dict( (target, i) for (i, target) in enumerate(problem.gtargets)) population, _, llk = stage.step.select_end_points(stage.mtrace) posterior_idxs = get_fit_indexes(llk) idx = posterior_idxs[po.post_llk] out_point = population[idx] results = problem.assemble_geodetic_results(out_point) nrmax = len(results) target_to_result = {} for target, result in zip(problem.gtargets, results): target_to_result[target] = result nfigs = int(num.ceil(float(nrmax) / float(ndmax))) figures = [] axes = [] for f in range(nfigs): fig, ax = plt.subplots( nrows=ndmax, ncols=nxmax, figsize=mpl_papersize('a4', 'portrait')) fig.tight_layout() fig.subplots_adjust( left=0.08, right=1.0 - 0.03, bottom=0.06, top=1.0 - 0.06, wspace=0., hspace=0.3) figures.append(fig) axes.append(ax) def axis_config(axes, po): axes[1].get_yaxis().set_ticklabels([]) axes[2].get_yaxis().set_ticklabels([]) axes[1].get_xaxis().set_ticklabels([]) axes[2].get_xaxis().set_ticklabels([]) if po.plot_projection == 'latlon': ystr = 'Latitude [deg]' xstr = 'Longitude [deg]' elif po.plot_projection == 'utm': ystr = 'UTM Northing [km]' xstr = 'UTM Easting [km]' elif po.plot_projection == 'local': ystr = 'Distance [km]' xstr = 'Distance [km]' else: raise Exception( 'Plot projection %s not available' % po.plot_projection) axes[0].set_ylabel(ystr, fontsize=fontsize) axes[0].set_xlabel(xstr, fontsize=fontsize) def draw_sources(ax, sources, po, **kwargs): for source in sources: rf = source.patches(1, 1, 'seismic')[0] if po.plot_projection == 'latlon': outline = rf.outline(cs='lonlat') elif po.plot_projection == 'utm': outline = rf.outline(cs='lonlat') utme, utmn = utility.lonlat_to_utm( lon=outline[:, 0], lat=outline[:, 1], zone=po.utm_zone) outline = num.vstack([utme / km, utmn / km]).T elif po.plot_projection == 'local': outline = rf.outline(cs='xy') ax.plot(outline[:, 0], outline[:, 1], '-', linewidth=1.0, **kwargs) ax.plot( outline[0:2, 0], outline[0:2, 1], '-k', linewidth=1.0) def cbtick(x): rx = math.floor(x * 1000.) / 1000. return [-rx, rx] def str_title(track): if track[0] == 'A': orbit = 'ascending' elif track[0] == 'D': orbit = 'descending' title = 'Orbit: ' + orbit return title orbits_to_targets = utility.gather( problem.gtargets, lambda t: t.track, filter=lambda t: t in target_to_result) ott = orbits_to_targets.keys() colims = [num.max([ num.max(num.abs(r.processed_obs)), num.max(num.abs(r.processed_syn))]) for r in results] dcolims = [num.max(num.abs(r.processed_res)) for r in results] for o in ott: targets = orbits_to_targets[o] for target in targets: if po.plot_projection == 'local': target.update_local_coords(problem.event) result = target_to_result[target] tidx = target_index[target] figidx, rowidx = utility.mod_i(tidx, ndmax) plot_scene( axes[figidx][rowidx, 0], target, result.processed_obs, scattersize, colim=colims[tidx], outmode=po.plot_projection, cmap=cmap) syn = plot_scene( axes[figidx][rowidx, 1], target, result.processed_syn, scattersize, colim=colims[tidx], outmode=po.plot_projection, cmap=cmap) res = plot_scene( axes[figidx][rowidx, 2], target, result.processed_res, scattersize, colim=dcolims[tidx], outmode=po.plot_projection, cmap=cmap) titley = 0.91 titlex = 0.16 axes[figidx][rowidx, 0].annotate( o, xy=(titlex, titley), xycoords='axes fraction', xytext=(2., 2.), textcoords='offset points', weight='bold', fontsize=fontsize_title) syn_color = scolor('plum1') ref_color = scolor('aluminium3') draw_sources( axes[figidx][rowidx, 1], problem.sources, po, color=syn_color) if po.reference is not None: draw_sources( axes[figidx][rowidx, 1], ref_sources, po, color=ref_color) cbb = 0.68 - (0.3175 * rowidx) cbl = 0.46 cbw = 0.15 cbh = 0.01 cbaxes = figures[figidx].add_axes([cbl, cbb, cbw, cbh]) dcbaxes = figures[figidx].add_axes([cbl + 0.3, cbb, cbw, cbh]) cblabel = 'LOS displacement [m]' cbs = plt.colorbar(syn, ax=axes[figidx][rowidx, 0], ticks=cbtick(colims[tidx]), cax=cbaxes, orientation='horizontal', cmap=cmap) cbs.set_label(cblabel, fontsize=fontsize) cbr = plt.colorbar(res, ax=axes[figidx][rowidx, 2], ticks=cbtick(dcolims[tidx]), cax=dcbaxes, orientation='horizontal', cmap=cmap) cbr.set_label(cblabel, fontsize=fontsize) axis_config(axes[figidx][rowidx, :], po) title = str_title(o) + ' Llk_' + po.post_llk figures[figidx].suptitle( title, fontsize=fontsize_title, weight='bold') nplots = ndmax * nfigs for delidx in range(nrmax, nplots): figidx, rowidx = utility.mod_i(delidx, ndmax) for colidx in range(nxmax): figures[figidx].delaxes(axes[figidx][rowidx, colidx]) return figures