Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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