def test_midpoint(self):
        center_lons = num.linspace(0., 180., 5)
        center_lats = [0., 89.]
        npoints = 10000
        half_side_length = 1000000.
        distance_error_max = 50000.
        for lat in center_lats:
            for lon in center_lons:
                n = num.random.uniform(
                    -half_side_length, half_side_length, npoints)
                e = num.random.uniform(
                    -half_side_length, half_side_length, npoints)
                dlats, dlons = orthodrome.ne_to_latlon(lat, lon, n, e)
                clat, clon = orthodrome.geographic_midpoint(dlats, dlons)
                d = orthodrome.distance_accurate50m_numpy(
                    clat, clon, lat, lon)[0]

                if plot:
                    import matplotlib.pyplot as plt
                    fig = plt.figure()
                    ax = fig.add_subplot(111)
                    ax.scatter(n, e)
                    c_n, c_e = orthodrome.latlon_to_ne_numpy(
                        lat, lon, clat, clon)
                    ax.plot(c_n, c_e, 'ro')
                    plt.show()

                self.assertTrue(d < distance_error_max, 'Distance %s > %s' %
                                (d, distance_error_max) +
                                '(maximum error)\n tested lat/lon: %s/%s' %
                                (lat, lon))
Example #2
0
def bounding_box(lat, lon, north, east, depth, scale=1.0):
    lat, lon, north, east, depth = float_array_broadcast(
        lat, lon, north, east, depth)

    if num.all(lat[0] == lat) and num.all(lon[0] == lon):

        return _scaled_bb(lat[0], lon[0], (num.min(north), num.max(north)),
                          (num.min(east), num.max(east)),
                          (num.min(depth), num.max(depth)), scale)

    else:
        elat, elon = od.ne_to_latlon(lat, lon, north, east)
        enorth, eeast = od.latlon_to_ne_numpy(elat[0], elon[0], elat, elon)
        enorth_min = num.min(enorth)
        enorth_max = num.max(enorth)
        eeast_min = num.min(eeast)
        eeast_max = num.max(eeast)

        mnorth = 0.5 * (enorth_min + enorth_max)
        meast = 0.5 * (eeast_min + eeast_max)

        lat0, lon0 = od.ne_to_latlon(elat[0], elon[0], mnorth, meast)
        return _scaled_bb(lat0, lon0,
                          (enorth_min - mnorth, enorth_max - mnorth),
                          (eeast_min - meast, eeast_max - meast),
                          (num.min(depth), num.max(depth)), scale)
Example #3
0
    def process(sources, sandbox, nthreads=0):
        result = {
            'processor_profile': dict(),
            'displacement.n': num.zeros(sandbox.frame.npixel),
            'displacement.e': num.zeros(sandbox.frame.npixel),
            'displacement.d': num.zeros(sandbox.frame.npixel),
        }

        src_nu = set(src.nu for src in sources)

        for nu in src_nu:
            nu_sources = [src for src in sources if src.nu == nu]
            nsources = len(nu_sources)
            src_arr = num.vstack([src.dislocSource() for src in nu_sources])

            north_shifts, east_shifts = od.latlon_to_ne_numpy(
                num.repeat(sandbox.frame.llLat, nsources),
                num.repeat(sandbox.frame.llLon, nsources),
                num.array([src.lat for src in nu_sources]),
                num.array([src.lon for src in nu_sources]))

            src_arr[:, 5] += east_shifts
            src_arr[:, 6] += north_shifts

            res = disloc_ext.disloc(src_arr, sandbox.frame.coordinatesMeter,
                                    nu, nthreads)

            result['displacement.e'] += res[:, 0]
            result['displacement.n'] += res[:, 1]
            result['displacement.d'] += -res[:, 2]

        return result
Example #4
0
    def test_midpoint(self):
        center_lons = num.linspace(0., 180., 5)
        center_lats = [0., 89.]
        npoints = 10000
        half_side_length = 1000000.
        distance_error_max = 50000.
        for lat in center_lats:
            for lon in center_lons:
                n = num.random.uniform(-half_side_length, half_side_length,
                                       npoints)
                e = num.random.uniform(-half_side_length, half_side_length,
                                       npoints)
                dlats, dlons = orthodrome.ne_to_latlon(lat, lon, n, e)
                clat, clon = orthodrome.geographic_midpoint(dlats, dlons)
                d = orthodrome.distance_accurate50m_numpy(
                    clat, clon, lat, lon)[0]

                if plot:
                    import matplotlib.pyplot as plt
                    fig = plt.figure()
                    ax = fig.add_subplot(111)
                    ax.scatter(n, e)
                    c_n, c_e = orthodrome.latlon_to_ne_numpy(
                        lat, lon, clat, clon)
                    ax.plot(c_n, c_e, 'ro')
                    plt.show()

                self.assertTrue(
                    d < distance_error_max,
                    'Distance %s > %s' % (d, distance_error_max) +
                    '(maximum error)\n tested lat/lon: %s/%s' % (lat, lon))
Example #5
0
def block_geometry(lons, lats, sources, reference):
    """
    Construct block geometry determine stable and moving parts dependend
    on the reference location.

    Parameters
    ----------
    lons : :class:`num.ndarray`
        Longitudes [deg] of observation points
    lats : :class:`num.ndarray`
        Latitudes [deg] of observation points
    sources : list
        of RectangularFault objects
    reference : :class:`heart.ReferenceLocation`
        reference location that determines the stable block

    Returns
    -------
    :class:`num.ndarray`
        mask with zeros/ones for stable/moving observation points, respectively
    """

    norths, easts = orthodrome.latlon_to_ne_numpy(reference.lat, reference.lon,
                                                  lats, lons)

    return block_mask(easts, norths, sources, east_ref=0., north_ref=0.)
Example #6
0
    def _calculateMeterGrid(self):
        if self.isMeter():
            raise ValueError(
                "Frame is defined in meter! " "Use gridE and gridN for meter grids"
            )

        if self._meter_grid is None:
            self._log.debug("Transforming latlon grid to meters...")
            gridN, gridE = latlon_to_ne_numpy(
                self.llLat,
                self.llLon,
                self.llLat + self.gridN.data.ravel(),
                self.llLon + self.gridE.data.ravel(),
            )

            valid_data = num.isnan(self._scene.displacement)
            gridE = num.ma.masked_array(
                gridE.reshape(self.gridE.shape), valid_data, fill_value=num.nan
            )
            gridN = num.ma.masked_array(
                gridN.reshape(self.gridN.shape), valid_data, fill_value=num.nan
            )
            self._meter_grid = (gridE, gridN)

        return self._meter_grid
Example #7
0
class TestInterseismic(unittest.TestCase):

    def __init__(self, *args, **kwargs):
        unittest.TestCase.__init__(self, *args, **kwargs)

        self.reference = None
        self.amplitude = 0.02
        self.azimuth = 115.
        self.locking_depth = [6.3, 5.0]

    def _get_store_superdir(self):
        return os.path.abspath('data/')

    def _get_gf_store(self, crust_ind):
        store_superdir = self._get_store_superdir(self)
        return os.path.join(store_superdir, 'psgrn_green_%i' % crust_ind)

    def _get_synthetic_data(self):
        lon = num.linspace(10.5, 13.5, 100.)
        lat = num.linspace(44.0, 46.0, 100.)

        Lon, Lat = num.meshgrid(lon, lat)
        reference = ReferenceLocation(
            lon=5., lat=45.)

        self.lons = Lon.flatten()
        self.lats = Lat.flatten()
        self.reference = reference

    def _get_sources(self, case=1):
        if case == 1:
            sources = [
                pscmp.PsCmpRectangularSource(
                    lon=12., lat=45., strike=20., dip=90., length=125. * km),
                pscmp.PsCmpRectangularSource(
                    lon=11.25, lat=44.35, strike=70., dip=90., length=80. * km)]

        elif case == 2:
            sources = [
                pscmp.PsCmpRectangularSource(
                    lon=12.04, lat=45.000, strike= 329.35 -180, dip=90.,
                    length=117809.04),
                pscmp.PsCmpRectangularSource(
                    lon=11.5, lat=45.75, strike=357.04-180, dip=90.,
                    length=80210.56)]

        for source in sources:
            north_shift, east_shift = orthodrome.latlon_to_ne_numpy(
                self.reference.lat,
                self.reference.lon,
                source.effective_lat,
                source.effective_lon,
                )
            source.update(
                lat=self.reference.lat, lon=self.reference.lon,
                north_shift=north_shift, east_shift=east_shift)
            print source

        return sources
Example #8
0
def mean_latlondist(lats, lons):
    if len(lats) == 0:
        return 0., 0., 1000.
    else:
        ns, es = od.latlon_to_ne_numpy(lats[0], lons[0], lats, lons)
        n, e = num.mean(ns), num.mean(es)
        dists = num.sqrt((ns - n)**2 + (es - e)**2)
        lat, lon = od.ne_to_latlon(lats[0], lons[0], n, e)
        return float(lat), float(lon), float(num.max(dists))
 def set_origin(self, lat, lon):
     lat = float(lat)
     lon = float(lon)
     elat, elon = self.effective_latlon
     n, e = orthodrome.latlon_to_ne_numpy(lat, lon, elat, elon)
     self.lat = lat
     self.lon = lon
     self.north_shift = float(n)
     self.east_shift = float(e)
     self._latlon = elat, elon  # unchanged
Example #10
0
 def set_origin(self, lat, lon):
     lat = float(lat)
     lon = float(lon)
     elat, elon = self.effective_latlon
     n, e = orthodrome.latlon_to_ne_numpy(lat, lon, elat, elon)
     self.lat = lat
     self.lon = lon
     self.north_shift = float(n)
     self.east_shift = float(e)
     self._latlon = elat, elon  # unchanged
def scaled_mesh(xin, yin):
    x, y = num.meshgrid(xin, yin)
    xs = num.zeros(x.shape)
    ys = num.zeros(y.shape)
    olats = num.zeros(y.shape[1])
    olons = num.zeros(x.shape[1])

    for i in xrange(len(x)):
        xs[i], ys[i] = od.latlon_to_ne_numpy(olats, olons, y[i], x[i])

    return xs, ys
Example #12
0
 def surface_points(self, system='latlon'):
     x, y, z = self._get_coords()
     xs = num.tile(x, y.size)
     ys = num.repeat(y, x.size)
     if system == 'latlon':
         return od.ne_to_latlon(self.lat, self.lon, xs, ys)
     elif system[0] == 'ne':
         lat0, lon0 = system[1:]
         if lat0 == self.lat and lon0 == self.lon:
             return xs, ys
         else:
             elats, elons = od.ne_to_latlon(self.lat, self.lon, xs, ys)
             return od.latlon_to_ne_numpy(lat0, lon0, elats, elons)
def get_shifts(stations, center_station, bazis, slownesses):
    ''' shape = (len(bazi), len(slow))'''
    lats = num.array([s.lat for s in stations])
    lons = num.array([s.lon for s in stations])
    lat0 = num.array([center_station.lat] * len(stations))
    lon0 = num.array([center_station.lon] * len(stations))
    ns, es = ortho.latlon_to_ne_numpy(lat0, lon0, lats, lons)
    station_vector = num.array((ns, es)).T
    bazis = bazis * d2r
    shifts = num.zeros((len(bazis)*len(slownesses), len(stations)))
    ishift = 0
    for ibazi, bazi in enumerate(bazis):
        s_vector = num.array((num.cos(bazi), num.sin(bazi)))
        for islowness, slowness in enumerate(slownesses):
            shifts[ishift] = station_vector.dot(s_vector) * slowness
            ishift += 1

    return shifts
Example #14
0
def get_shifts(stations, center_station, bazis, slownesses):
    ''' shape = (len(bazi), len(slow))'''
    lats = num.array([s.lat for s in stations])
    lons = num.array([s.lon for s in stations])
    lat0 = num.array([center_station.lat] * len(stations))
    lon0 = num.array([center_station.lon] * len(stations))
    ns, es = ortho.latlon_to_ne_numpy(lat0, lon0, lats, lons)
    station_vector = num.array((ns, es)).T
    bazis = bazis * d2r
    shifts = num.zeros((len(bazis) * len(slownesses), len(stations)))
    ishift = 0
    for ibazi, bazi in enumerate(bazis):
        s_vector = num.array((num.cos(bazi), num.sin(bazi)))
        for islowness, slowness in enumerate(slownesses):
            shifts[ishift] = station_vector.dot(s_vector) * slowness
            ishift += 1

    return shifts
    def locations_to_ned(self, locations, has_elevation=False):
        npoints = len(locations)
        lats = num.zeros(npoints)
        lons = num.zeros(npoints)
        depths = num.zeros(npoints)

        for i_e, e in enumerate(locations):
            lats[i_e] = float(e.lat)
            lons[i_e] = float(e.lon)
            if has_elevation:
                depths[i_e] = float(e.depth) - float(e.elevation)
            else:
                depths[i_e] = float(e.depth)

        depths *= self.z_scale
        nz = num.zeros(npoints)
        ns, es = ortho.latlon_to_ne_numpy(nz, nz, lats, lons)

        return ns, es, depths
Example #16
0
def locations_to_ned(locations, has_elevation=False, z_scale=1.):
    npoints = len(locations)
    lats = num.zeros(npoints)
    lons = num.zeros(npoints)
    depths = num.zeros(npoints)

    for i_e, e in enumerate(locations):
        lats[i_e] = float(e.lat)
        lons[i_e] = float(e.lon)
        if has_elevation:
            depths[i_e] = float(e.depth) - float(e.elevation)
        else:
            depths[i_e] = float(e.depth)

    depths *= z_scale
    nz = num.zeros(npoints)
    ns, es = ortho.latlon_to_ne_numpy(nz, nz, lats, lons)

    return ns, es, depths
Example #17
0
def points_coords(points, system=None):
    a = num.zeros((len(points), 5))
    for ir, r in enumerate(points):
        a[ir, :] = r.vec

    lats, lons, xs, ys, zs = a.T

    if system is None:
        return (lats, lons, xs, ys, zs)

    elif system == 'latlon':
        return od.ne_to_latlon(lats, lons, xs, ys)

    elif system[0] == 'ne':
        lat0, lon0 = system[1:3]
        if num.all(lats == lat0) and num.all(lons == lon0):
            return xs, ys
        else:
            elats, elons = od.ne_to_latlon(lats, lons, xs, ys)
            return od.latlon_to_ne_numpy(lat0, lon0, elats, elons)
Example #18
0
    def pointCDMParameters(self):
        if self._sandbox:
            east_shift, north_shift = od.latlon_to_ne_numpy(
                self._sandbox.frame.llLat, self._sandbox.frame.llLon, self.lat,
                self.lon)
        else:
            east_shift = 0.
            north_shift = 0.

        params = {
            'x0': self.easting + east_shift,
            'y0': self.northing + north_shift,
            'z0': self.depth,
            'rotx': self.rotation_x,
            'roty': self.rotation_y,
            'rotz': self.rotation_z,
            'dVx': self.dVx**3,
            'dVy': self.dVy**3,
            'dVz': self.dVz**3,
            'nu': self.nu
        }
        return params
Example #19
0
    def pointCDMParameters(self):
        if self._sandbox:
            east_shift, north_shift = od.latlon_to_ne_numpy(
                self._sandbox.frame.llLat, self._sandbox.frame.llLon, self.lat, self.lon
            )
        else:
            east_shift = 0.0
            north_shift = 0.0

        params = {
            "x0": self.easting + east_shift,
            "y0": self.northing + north_shift,
            "z0": self.depth,
            "rotx": self.rotation_x,
            "roty": self.rotation_y,
            "rotz": self.rotation_z,
            "dVx": self.dVx**3,
            "dVy": self.dVy**3,
            "dVz": self.dVz**3,
            "nu": self.nu,
        }
        return params
Example #20
0
    def ECMParameters(self):
        if self._sandbox:
            east_shift, north_shift = od.latlon_to_ne_numpy(
                self._sandbox.frame.llLat, self._sandbox.frame.llLon, self.lat, self.lon
            )
        else:
            east_shift = 0.0
            north_shift = 0.0

        params = {
            "x0": self.easting + east_shift,
            "y0": self.northing + north_shift,
            "z0": self.depth,
            "rotx": self.rotation_x,
            "roty": self.rotation_y,
            "rotz": self.rotation_z,
            "ax": self.length_x,
            "ay": self.length_y,
            "az": self.length_z,
            "P": self.cavity_pressure * 1e9,
            "mu": self.mu * 1e9,
            "lamda": self.lamda * 1e9,
        }
        return params
Example #21
0
    def ECMParameters(self):
        if self._sandbox:
            east_shift, north_shift = od.latlon_to_ne_numpy(
                self._sandbox.frame.llLat, self._sandbox.frame.llLon, self.lat,
                self.lon)
        else:
            east_shift = 0.
            north_shift = 0.

        params = {
            'x0': self.easting + east_shift,
            'y0': self.northing + north_shift,
            'z0': self.depth,
            'rotx': self.rotation_x,
            'roty': self.rotation_y,
            'rotz': self.rotation_z,
            'ax': self.length_x,
            'ay': self.length_y,
            'az': self.length_z,
            'P': self.cavity_pressure * 1e9,
            'mu': self.mu * 1e9,
            'lamda': self.lamda * 1e9
        }
        return params
Example #22
0
    def make_time_line(self, markers, stations=None, cmap=cmap):
        events = [m.get_event() for m in markers]
        kinds = num.array([m.kind for m in markers])
        if self.cli_mode:
            self.fig = plt.figure()
        else:
            fframe = self.figure_frame()
            self.fig = fframe.gcf()
        ax = self.fig.add_subplot(311)
        ax_cum = ax.twinx()
        ax1 = self.fig.add_subplot(323)
        ax2 = self.fig.add_subplot(325, sharex=ax1)
        ax3 = self.fig.add_subplot(324, sharey=ax1)

        num_events = len(events)
        data = num.zeros((num_events, 6))
        column_to_index = dict(zip(['magnitude', 'latitude', 'longitude', 'depth', 'time', 'kind'],
                           range(6)))
        c2i = column_to_index
        for i, e in enumerate(events):
            if e.magnitude:
                mag = e.magnitude
            else:
                mag = 0.
            data[i, :] = mag, e.lat, e.lon, e.depth, e.time, kinds[i]

        s_coords = num.array([])
        s_labels = []
        if stations is not None:
            s_coords = num.array([(s.lon, s.lat, s.elevation-s.depth) for s in stations])
            s_labels = ['.'.join(s.nsl()) for s in stations]

        isorted = num.argsort(data[:, c2i['time']])
        data = data[isorted]

        def _D(key):
            return data[:, c2i[key]]

        tmin = _D('time').min()
        tmax = _D('time').max()
        lon_max = _D('longitude').max()
        lon_min = _D('longitude').min()
        lat_max = _D('latitude').max()
        lat_min = _D('latitude').min()
        depths_min = _D('depth').min()
        depths_max = _D('depth').max()
        mags_min = _D('magnitude').min()
        mags_max = _D('magnitude').max()
        moments = moment_tensor.magnitude_to_moment(_D('magnitude'))
        dates = list(map(datetime.fromtimestamp, _D('time')))

        fds = mdates.date2num(dates)
        tday = 3600*24
        tweek = tday*7
        if tmax-tmin < 1*tday:
            hfmt = mdates.DateFormatter('%Y-%m-%d %H:%M:%S')
        elif tmax-tmin < tweek*52:
            hfmt = mdates.DateFormatter('%Y-%m-%d')
        else:
            hfmt = mdates.DateFormatter('%Y/%m')

        color_values = _D(self.color_by)
        color_args = dict(c=color_values, vmin=color_values.min(),
                    vmax=color_values.max(), cmap=cmap)

        ax.scatter(fds, _D('magnitude'), s=20, **color_args)

        ax.xaxis.set_major_formatter(hfmt)
        ax.spines['top'].set_color('none')
        ax.spines['right'].set_color('none')
        ax.set_ylim((mags_min, mags_max*1.10))
        ax.set_xlim(map(datetime.fromtimestamp, (tmin, tmax)))
        ax.xaxis.set_ticks_position('bottom')
        ax.yaxis.set_ticks_position('left')
        ax.set_ylabel('Magnitude')
        init_pos = ax.get_position()

        ax_cum.plot(fds, num.cumsum(moments), 'grey')
        ax_cum.xaxis.set_major_formatter(hfmt)
        ax_cum.spines['top'].set_color('none')
        ax_cum.spines['right'].set_color('grey')
        ax_cum.set_ylabel('Cumulative seismic moment')

        lats_min = num.array([lat_min for x in range(num_events)])
        lons_min = num.array([lon_min for x in range(num_events)])

        if self.coord_system == 'cartesian':
            lats, lons = orthodrome.latlon_to_ne_numpy(
                lats_min, lons_min, _D('latitude'), _D('longitude'))

            _x = num.empty((len(s_coords), 3))
            for i, (slon, slat, sele) in enumerate(s_coords):
                n, e = orthodrome.latlon_to_ne(lat_min, lon_min, slat, slon)
                _x[i, :] = (e, n, sele)
            s_coords = _x
        else:
            lats = _D('latitude')
            lons = _D('longitude')

        s_coords = s_coords.T

        ax1.scatter(lons, lats, s=20, **color_args)
        ax1.set_aspect('equal')
        ax1.grid(True, which='both')
        ax1.set_ylabel('Northing [m]')
        ax1.get_yaxis().tick_left()

        if len(s_coords):
            ax1.scatter(s_coords[0], s_coords[1], marker='v', s=40, color='black')
            for c, sl in zip(s_coords.T, s_labels):
                ax1.text(c[0], c[1], sl, color='black')

        # bottom left plot
        ax2.scatter(lons, _D('depth'), s=20, **color_args)
        ax2.grid(True)
        ax2.set_xlabel('Easting [m]')
        ax2.set_ylabel('Depth [m]')
        ax2.get_yaxis().tick_left()
        ax2.get_xaxis().tick_bottom()
        ax2.invert_yaxis()

        ax2.text(1.1, 0, 'Origin at:\nlat=%1.3f, lon=%1.3f' %
                 (lat_min, lon_min), transform=ax2.transAxes)

        # top right plot
        ax3.scatter(_D('depth'), lats, s=20, **color_args)
        ax3.set_xlim((depths_min, depths_max))
        ax3.grid(True)
        ax3.set_xlabel('Depth [m]')
        ax3.get_xaxis().tick_bottom()
        ax3.get_yaxis().tick_right()

        self.fig.subplots_adjust(
            bottom=0.05, right=0.95, left=0.075, top=0.95, wspace=0.02, hspace=0.02)
        init_pos.y0 += 0.05
        ax.set_position(init_pos)
        ax_cum.set_position(init_pos)
        if self.cli_mode:
            plt.show()
        else:
            self.fig.canvas.draw()
Example #23
0
    def draw_static_fits(self, ds, history, optimiser, closeup=False):
        from pyrocko.orthodrome import latlon_to_ne_numpy
        problem = history.problem

        sat_targets = problem.satellite_targets
        for target in sat_targets:
            target.set_dataset(ds)

        source = history.get_best_source()
        best_model = history.get_best_model()
        results = problem.evaluate(best_model, targets=sat_targets)

        def initAxes(ax, scene, title, last_axes=False):
            ax.set_title(title)
            ax.tick_params(length=2)

            if scene.frame.isMeter():
                ax.set_xlabel('Easting [km]')
                scale_x = {'scale': 1. / km}
                scale_y = {'scale': 1. / km}
                if not self.relative_coordinates:
                    import utm
                    utm_E, utm_N, utm_zone, utm_zone_letter =\
                        utm.from_latlon(source.effective_lat,
                                        source.effective_lon)
                    scale_x['offset'] = utm_E
                    scale_y['offset'] = utm_N

                    if last_axes:
                        ax.text(0.975,
                                0.025,
                                'UTM Zone %d%s' % (utm_zone, utm_zone_letter),
                                va='bottom',
                                ha='right',
                                fontsize=8,
                                alpha=.7,
                                transform=ax.transAxes)
                ax.set_aspect('equal')

            elif scene.frame.isDegree():
                ax.set_xlabel('Lon [°]')
                scale_x = {'scale': 1.}
                scale_y = {'scale': 1.}
                if not self.relative_coordinates:
                    scale_x['offset'] = source.effective_lon
                    scale_y['offset'] = source.effective_lat
                ax.set_aspect(1. / num.cos(source.effective_lat * d2r))

            scale_axes(ax.get_xaxis(), **scale_x)
            scale_axes(ax.get_yaxis(), **scale_y)

        def drawSource(ax, scene):
            if scene.frame.isMeter():
                fn, fe = source.outline(cs='xy').T
                fn -= fn.mean()
                fe -= fe.mean()
            elif scene.frame.isDegree():
                fn, fe = source.outline(cs='latlon').T
                fn -= source.effective_lat
                fe -= source.effective_lon

            # source is centered
            ax.scatter(0., 0., color='black', s=3, alpha=.5, marker='o')
            ax.fill(fe,
                    fn,
                    edgecolor=(0., 0., 0.),
                    facecolor=(.5, .5, .5),
                    alpha=0.7)
            ax.plot(fe[0:2], fn[0:2], 'k', linewidth=1.3)

        def mapDisplacementGrid(displacements, scene):
            arr = num.full_like(scene.displacement, fill_value=num.nan)
            qt = scene.quadtree

            for syn_v, l in zip(displacements, qt.leaves):
                arr[l._slice_rows, l._slice_cols] = syn_v

            arr[scene.displacement_mask] = num.nan
            return arr

        def drawLeaves(ax, scene, offset_e=0., offset_n=0.):
            rects = scene.quadtree.getMPLRectangles()
            for r in rects:
                r.set_edgecolor((.4, .4, .4))
                r.set_linewidth(.5)
                r.set_facecolor('none')
                r.set_x(r.get_x() - offset_e)
                r.set_y(r.get_y() - offset_n)
            map(ax.add_artist, rects)

            ax.scatter(scene.quadtree.leaf_coordinates[:, 0] - offset_e,
                       scene.quadtree.leaf_coordinates[:, 1] - offset_n,
                       s=.25,
                       c='black',
                       alpha=.1)

        def addArrow(ax, scene):
            phi = num.nanmean(scene.phi)
            los_dx = num.cos(phi + num.pi) * .0625
            los_dy = num.sin(phi + num.pi) * .0625

            az_dx = num.cos(phi - num.pi / 2) * .125
            az_dy = num.sin(phi - num.pi / 2) * .125

            anchor_x = .9 if los_dx < 0 else .1
            anchor_y = .85 if los_dx < 0 else .975

            az_arrow = patches.FancyArrow(x=anchor_x - az_dx,
                                          y=anchor_y - az_dy,
                                          dx=az_dx,
                                          dy=az_dy,
                                          head_width=.025,
                                          alpha=.5,
                                          fc='k',
                                          head_starts_at_zero=False,
                                          length_includes_head=True,
                                          transform=ax.transAxes)

            los_arrow = patches.FancyArrow(x=anchor_x - az_dx / 2,
                                           y=anchor_y - az_dy / 2,
                                           dx=los_dx,
                                           dy=los_dy,
                                           head_width=.02,
                                           alpha=.5,
                                           fc='k',
                                           head_starts_at_zero=False,
                                           length_includes_head=True,
                                           transform=ax.transAxes)

            ax.add_artist(az_arrow)
            ax.add_artist(los_arrow)

        urE, urN, llE, llN = (0., 0., 0., 0.)
        for target in sat_targets:

            if target.scene.frame.isMeter():
                off_n, off_e = map(
                    float,
                    latlon_to_ne_numpy(target.scene.frame.llLat,
                                       target.scene.frame.llLon,
                                       source.effective_lat,
                                       source.effective_lon))
            if target.scene.frame.isDegree():
                off_n = source.effective_lat - target.scene.frame.llLat
                off_e = source.effective_lon - target.scene.frame.llLon

            turE, turN, tllE, tllN = zip(
                *[(l.gridE.max() - off_e, l.gridN.max() - off_n,
                   l.gridE.min() - off_e, l.gridN.min() - off_n)
                  for l in target.scene.quadtree.leaves])

            turE, turN = map(max, (turE, turN))
            tllE, tllN = map(min, (tllE, tllN))
            urE, urN = map(max, ((turE, urE), (urN, turN)))
            llE, llN = map(min, ((tllE, llE), (llN, tllN)))

        def generate_plot(sat_target, result, ifig):

            scene = sat_target.scene

            fig = plt.figure()
            fig.set_size_inches(*self.size_inch)
            gs = gridspec.GridSpec(2,
                                   3,
                                   wspace=.15,
                                   hspace=.2,
                                   left=.1,
                                   right=.975,
                                   top=.95,
                                   height_ratios=[12, 1])

            item = PlotItem(name='fig_%i' % ifig,
                            attributes={'targets': [sat_target.path]},
                            title=u'Satellite Surface Displacements - %s' %
                            scene.meta.scene_title,
                            description=u'''
Surface displacements derived from satellite data.
(Left) the input data, (center) the modelled
data and (right) the model residual.
'''.format(meta=scene.meta))

            stat_obs = result.statics_obs
            stat_syn = result.statics_syn['displacement.los']
            res = stat_obs - stat_syn

            if scene.frame.isMeter():
                offset_n, offset_e = map(
                    float,
                    latlon_to_ne_numpy(scene.frame.llLat, scene.frame.llLon,
                                       source.effective_lat,
                                       source.effective_lon))
            elif scene.frame.isDegree():
                offset_n = source.effective_lat - scene.frame.llLat
                offset_e = source.effective_lon - scene.frame.llLon

            im_extent = (scene.frame.E.min() - offset_e, scene.frame.E.max() -
                         offset_e, scene.frame.N.min() - offset_n,
                         scene.frame.N.max() - offset_n)

            abs_displ = num.abs([
                stat_obs.min(),
                stat_obs.max(),
                stat_syn.min(),
                stat_syn.max(),
                res.min(),
                res.max()
            ]).max()

            cmw = cm.ScalarMappable(cmap=self.colormap)
            cmw.set_clim(vmin=-abs_displ, vmax=abs_displ)
            cmw.set_array(stat_obs)

            axes = [
                fig.add_subplot(gs[0, 0]),
                fig.add_subplot(gs[0, 1]),
                fig.add_subplot(gs[0, 2])
            ]

            ax = axes[0]
            ax.imshow(mapDisplacementGrid(stat_obs, scene),
                      extent=im_extent,
                      cmap=self.colormap,
                      vmin=-abs_displ,
                      vmax=abs_displ,
                      origin='lower')
            drawLeaves(ax, scene, offset_e, offset_n)
            drawSource(ax, scene)
            addArrow(ax, scene)
            initAxes(ax, scene, 'Observed')

            ax.text(.025,
                    .025,
                    'Scene ID: %s' % scene.meta.scene_id,
                    fontsize=8,
                    alpha=.7,
                    va='bottom',
                    transform=ax.transAxes)
            if scene.frame.isDegree():
                ax.set_ylabel('Lat [°]')
            elif scene.frame.isMeter():
                ax.set_ylabel('Northing [km]')

            ax = axes[1]
            ax.imshow(mapDisplacementGrid(stat_syn, scene),
                      extent=im_extent,
                      cmap=self.colormap,
                      vmin=-abs_displ,
                      vmax=abs_displ,
                      origin='lower')
            drawLeaves(ax, scene, offset_e, offset_n)
            drawSource(ax, scene)
            addArrow(ax, scene)
            initAxes(ax, scene, 'Model')
            ax.get_yaxis().set_visible(False)

            ax = axes[2]
            ax.imshow(mapDisplacementGrid(res, scene),
                      extent=im_extent,
                      cmap=self.colormap,
                      vmin=-abs_displ,
                      vmax=abs_displ,
                      origin='lower')
            drawLeaves(ax, scene, offset_e, offset_n)
            drawSource(ax, scene)
            addArrow(ax, scene)
            initAxes(ax, scene, 'Residual', last_axes=True)
            ax.get_yaxis().set_visible(False)

            for ax in axes:
                ax.set_xlim(llE, urE)
                ax.set_ylim(llN, urN)

            if closeup:
                if scene.frame.isMeter():
                    fn, fe = source.outline(cs='xy').T
                elif scene.frame.isDegree():
                    fn, fe = source.outline(cs='latlon').T
                    fn -= source.effective_lat
                    fe -= source.effective_lon

                if fn.size > 1:
                    off_n = (fn[0] + fn[1]) / 2
                    off_e = (fe[0] + fe[1]) / 2
                else:
                    off_n = fn[0]
                    off_e = fe[0]

                fault_size = 2 * num.sqrt(
                    max(abs(fn - off_n))**2 + max(abs(fe - off_e))**2)
                fault_size *= self.map_scale
                if fault_size == 0.0:
                    extent = (scene.frame.N[-1] + scene.frame.E[-1]) / 2
                    fault_size = extent * .25

                for ax in axes:
                    ax.set_xlim(-fault_size / 2 + off_e,
                                fault_size / 2 + off_e)
                    ax.set_ylim(-fault_size / 2 + off_n,
                                fault_size / 2 + off_n)

            cax = fig.add_subplot(gs[1, :])
            cbar = fig.colorbar(cmw,
                                cax=cax,
                                orientation='horizontal',
                                use_gridspec=True)

            cbar.set_label('LOS Displacement [m]')

            return (item, fig)

        for ifig, (sat_target, result) in enumerate(zip(sat_targets, results)):
            yield generate_plot(sat_target, result, ifig)
Example #24
0
        def generate_plot(sat_target, result, ifig):

            scene = sat_target.scene

            fig = plt.figure()
            fig.set_size_inches(*self.size_inch)
            gs = gridspec.GridSpec(2,
                                   3,
                                   wspace=.15,
                                   hspace=.2,
                                   left=.1,
                                   right=.975,
                                   top=.95,
                                   height_ratios=[12, 1])

            item = PlotItem(name='fig_%i' % ifig,
                            attributes={'targets': [sat_target.path]},
                            title=u'Satellite Surface Displacements - %s' %
                            scene.meta.scene_title,
                            description=u'''
Surface displacements derived from satellite data.
(Left) the input data, (center) the modelled
data and (right) the model residual.
'''.format(meta=scene.meta))

            stat_obs = result.statics_obs
            stat_syn = result.statics_syn['displacement.los']
            res = stat_obs - stat_syn

            if scene.frame.isMeter():
                offset_n, offset_e = map(
                    float,
                    latlon_to_ne_numpy(scene.frame.llLat, scene.frame.llLon,
                                       source.effective_lat,
                                       source.effective_lon))
            elif scene.frame.isDegree():
                offset_n = source.effective_lat - scene.frame.llLat
                offset_e = source.effective_lon - scene.frame.llLon

            im_extent = (scene.frame.E.min() - offset_e, scene.frame.E.max() -
                         offset_e, scene.frame.N.min() - offset_n,
                         scene.frame.N.max() - offset_n)

            abs_displ = num.abs([
                stat_obs.min(),
                stat_obs.max(),
                stat_syn.min(),
                stat_syn.max(),
                res.min(),
                res.max()
            ]).max()

            cmw = cm.ScalarMappable(cmap=self.colormap)
            cmw.set_clim(vmin=-abs_displ, vmax=abs_displ)
            cmw.set_array(stat_obs)

            axes = [
                fig.add_subplot(gs[0, 0]),
                fig.add_subplot(gs[0, 1]),
                fig.add_subplot(gs[0, 2])
            ]

            ax = axes[0]
            ax.imshow(mapDisplacementGrid(stat_obs, scene),
                      extent=im_extent,
                      cmap=self.colormap,
                      vmin=-abs_displ,
                      vmax=abs_displ,
                      origin='lower')
            drawLeaves(ax, scene, offset_e, offset_n)
            drawSource(ax, scene)
            addArrow(ax, scene)
            initAxes(ax, scene, 'Observed')

            ax.text(.025,
                    .025,
                    'Scene ID: %s' % scene.meta.scene_id,
                    fontsize=8,
                    alpha=.7,
                    va='bottom',
                    transform=ax.transAxes)
            if scene.frame.isDegree():
                ax.set_ylabel('Lat [°]')
            elif scene.frame.isMeter():
                ax.set_ylabel('Northing [km]')

            ax = axes[1]
            ax.imshow(mapDisplacementGrid(stat_syn, scene),
                      extent=im_extent,
                      cmap=self.colormap,
                      vmin=-abs_displ,
                      vmax=abs_displ,
                      origin='lower')
            drawLeaves(ax, scene, offset_e, offset_n)
            drawSource(ax, scene)
            addArrow(ax, scene)
            initAxes(ax, scene, 'Model')
            ax.get_yaxis().set_visible(False)

            ax = axes[2]
            ax.imshow(mapDisplacementGrid(res, scene),
                      extent=im_extent,
                      cmap=self.colormap,
                      vmin=-abs_displ,
                      vmax=abs_displ,
                      origin='lower')
            drawLeaves(ax, scene, offset_e, offset_n)
            drawSource(ax, scene)
            addArrow(ax, scene)
            initAxes(ax, scene, 'Residual', last_axes=True)
            ax.get_yaxis().set_visible(False)

            for ax in axes:
                ax.set_xlim(llE, urE)
                ax.set_ylim(llN, urN)

            if closeup:
                if scene.frame.isMeter():
                    fn, fe = source.outline(cs='xy').T
                elif scene.frame.isDegree():
                    fn, fe = source.outline(cs='latlon').T
                    fn -= source.effective_lat
                    fe -= source.effective_lon

                if fn.size > 1:
                    off_n = (fn[0] + fn[1]) / 2
                    off_e = (fe[0] + fe[1]) / 2
                else:
                    off_n = fn[0]
                    off_e = fe[0]

                fault_size = 2 * num.sqrt(
                    max(abs(fn - off_n))**2 + max(abs(fe - off_e))**2)
                fault_size *= self.map_scale
                if fault_size == 0.0:
                    extent = (scene.frame.N[-1] + scene.frame.E[-1]) / 2
                    fault_size = extent * .25

                for ax in axes:
                    ax.set_xlim(-fault_size / 2 + off_e,
                                fault_size / 2 + off_e)
                    ax.set_ylim(-fault_size / 2 + off_n,
                                fault_size / 2 + off_n)

            cax = fig.add_subplot(gs[1, :])
            cbar = fig.colorbar(cmw,
                                cax=cax,
                                orientation='horizontal',
                                use_gridspec=True)

            cbar.set_label('LOS Displacement [m]')

            return (item, fig)
Example #25
0
 def getSandboxOffset(self):
     if not self._sandbox or (self.lat == 0.0 and self.lon == 0.0):
         return 0.0, 0.0
     return od.latlon_to_ne_numpy(
         self._sandbox.frame.llLat, self._sandbox.frame.llLon, self.lat, self.lon
     )
    def test_point_in_polygon(self):
        if plot:
            from pyrocko.plot import mpl_graph_color

            import matplotlib.pyplot as plt
            from matplotlib.patches import Polygon

            axes = plt.gca()

        nip = 100

        for i in range(1):
            np = 3
            points = num.zeros((np, 2))
            points[:, 0] = random_lat(size=3)
            points[:, 1] = random_lon(size=3)

            points_ip = num.zeros((nip*points.shape[0], 2))
            for ip in range(points.shape[0]):
                n, e = orthodrome.latlon_to_ne_numpy(
                    points[ip % np, 0], points[ip % np, 1],
                    points[(ip+1) % np, 0], points[(ip+1) % np, 1])

                ns = num.arange(nip) * n / nip
                es = num.arange(nip) * e / nip
                lats, lons = orthodrome.ne_to_latlon(
                    points[ip % np, 0], points[ip % np, 1], ns, es)

                points_ip[ip*nip:(ip+1)*nip, 0] = lats
                points_ip[ip*nip:(ip+1)*nip, 1] = lons

            if plot:
                color = mpl_graph_color(i)
                axes.add_patch(
                    Polygon(
                        num.fliplr(points_ip),
                        facecolor=light(color),
                        edgecolor=color,
                        alpha=0.5))

            points_xyz = orthodrome.latlon_to_xyz(points_ip.T)
            center_xyz = num.mean(points_xyz, axis=0)

            assert num.all(
                orthodrome.distances3d(
                    points_xyz, center_xyz[num.newaxis, :]) < 1.0)

            lat, lon = orthodrome.xyz_to_latlon(center_xyz)
            rot = orthodrome.rot_to_00(lat, lon)

            points_rot_xyz = num.dot(rot, points_xyz.T).T
            points_rot_pro = orthodrome.stereographic(points_rot_xyz)  # noqa

            poly_xyz = orthodrome.latlon_to_xyz(points_ip)
            poly_rot_xyz = num.dot(rot, poly_xyz.T).T
            groups = orthodrome.spoly_cut([poly_rot_xyz], axis=0)
            num.zeros(points.shape[0], dtype=num.int)

            if plot:
                for group in groups:
                    for poly_rot_group_xyz in group:

                        axes.set_xlim(-180., 180.)
                        axes.set_ylim(-90., 90.)

                    plt.show()
Example #27
0
    def test_point_in_polygon(self):
        if plot:
            from pyrocko.plot import mpl_graph_color

            import matplotlib.pyplot as plt
            from matplotlib.patches import Polygon

            axes = plt.gca()

        nip = 100

        for i in range(1):
            np = 3
            points = num.zeros((np, 2))
            points[:, 0] = random_lat(size=3)
            points[:, 1] = random_lon(size=3)

            points_ip = num.zeros((nip*points.shape[0], 2))
            for ip in range(points.shape[0]):
                n, e = orthodrome.latlon_to_ne_numpy(
                    points[ip % np, 0], points[ip % np, 1],
                    points[(ip+1) % np, 0], points[(ip+1) % np, 1])

                ns = num.arange(nip) * n / nip
                es = num.arange(nip) * e / nip
                lats, lons = orthodrome.ne_to_latlon(
                    points[ip % np, 0], points[ip % np, 1], ns, es)

                points_ip[ip*nip:(ip+1)*nip, 0] = lats
                points_ip[ip*nip:(ip+1)*nip, 1] = lons

            if plot:
                color = mpl_graph_color(i)
                axes.add_patch(
                    Polygon(
                        num.fliplr(points_ip),
                        facecolor=light(color),
                        edgecolor=color,
                        alpha=0.5))

            points_xyz = orthodrome.latlon_to_xyz(points_ip.T)
            center_xyz = num.mean(points_xyz, axis=0)

            assert num.all(
                orthodrome.distances3d(
                    points_xyz, center_xyz[num.newaxis, :]) < 1.0)

            lat, lon = orthodrome.xyz_to_latlon(center_xyz)
            rot = orthodrome.rot_to_00(lat, lon)

            points_rot_xyz = num.dot(rot, points_xyz.T).T
            points_rot_pro = orthodrome.stereographic(points_rot_xyz)  # noqa

            poly_xyz = orthodrome.latlon_to_xyz(points_ip)
            poly_rot_xyz = num.dot(rot, poly_xyz.T).T
            groups = orthodrome.spoly_cut([poly_rot_xyz], axis=0)
            num.zeros(points.shape[0], dtype=num.int)

            if plot:
                for group in groups:
                    for poly_rot_group_xyz in group:

                        axes.set_xlim(-180., 180.)
                        axes.set_ylim(-90., 90.)

                    plt.show()
Example #28
0
    def draw_static_fits(self, ds, history, optimiser, closeup=False):
        from pyrocko.orthodrome import latlon_to_ne_numpy
        problem = history.problem

        sat_targets = problem.satellite_targets
        for target in sat_targets:
            target.set_dataset(ds)

        if self.fit == 'best':
            source = history.get_best_source()
            model = history.get_best_model()
        elif self.fit == 'mean':
            source = history.get_mean_source()
            model = history.get_mean_model()

        results = problem.evaluate(model, targets=sat_targets)

        def init_axes(ax, scene, title, last_axes=False):
            ax.set_title(title, fontsize=self.font_size)
            ax.tick_params(length=2)

            if scene.frame.isMeter():
                import utm
                ax.set_xlabel('Easting [km]', fontsize=self.font_size)
                scale_x = dict(scale=1./km)
                scale_y = dict(scale=1./km)
                utm_E, utm_N, utm_zone, utm_zone_letter =\
                    utm.from_latlon(source.effective_lat,
                                    source.effective_lon)
                scale_x['offset'] = utm_E
                scale_y['offset'] = utm_N

                if last_axes:
                    ax.text(0.975, 0.025,
                            'UTM Zone %d%s' % (utm_zone, utm_zone_letter),
                            va='bottom', ha='right',
                            fontsize=8, alpha=.7,
                            transform=ax.transAxes)
                ax.set_aspect('equal')

            elif scene.frame.isDegree():
                scale_x = dict(scale=1., suffix='°')
                scale_y = dict(scale=1., suffix='°')
                scale_x['offset'] = source.effective_lon
                scale_y['offset'] = source.effective_lat

                ax.set_aspect(1./num.cos(source.effective_lat*d2r))

            if self.relative_coordinates:
                scale_x['offset'] = 0.
                scale_y['offset'] = 0.

            nticks_x = 4 if abs(scene.frame.llLon) >= 100 else 5

            ax.xaxis.set_major_locator(MaxNLocator(self.nticks_x or nticks_x))
            ax.yaxis.set_major_locator(MaxNLocator(5))

            ax.scale_x = scale_x
            ax.scale_y = scale_y

            scale_axes(ax.get_xaxis(), **scale_x)
            scale_axes(ax.get_yaxis(), **scale_y)

        def draw_source(ax, scene):
            if scene.frame.isMeter():
                fn, fe = source.outline(cs='xy').T
                fn -= fn.mean()
                fe -= fe.mean()
            elif scene.frame.isDegree():
                fn, fe = source.outline(cs='latlon').T
                fn -= source.effective_lat
                fe -= source.effective_lon

            # source is centered
            ax.scatter(0., 0., color='black', s=3, alpha=.5, marker='o')
            ax.fill(fe, fn,
                    edgecolor=(0., 0., 0.),
                    facecolor=self.source_outline_color,
                    alpha=0.7)
            ax.plot(fe[0:2], fn[0:2], 'k', linewidth=1.3)

        def get_displacement_rgba(displacements, scene, mappable):
            arr = num.full_like(scene.displacement, fill_value=num.nan)
            qt = scene.quadtree

            for syn_v, leaf in zip(displacements, qt.leaves):
                arr[leaf._slice_rows, leaf._slice_cols] = syn_v

            arr[scene.displacement_mask] = num.nan

            if not self.common_color_scale \
                    and not self.displacement_unit == 'rad':
                abs_displ = num.abs(displacements).max()
                mappable.set_clim(-abs_displ, abs_displ)

            if self.show_topo:
                try:
                    elevation = scene.get_elevation()
                    return drape_displacements(arr, elevation, mappable)
                except Exception as e:
                    logger.warning('could not plot hillshaded topo')
                    logger.exception(e)

            return mappable.to_rgba(arr)

        def draw_leaves(ax, scene, offset_e=0., offset_n=0.):
            rects = scene.quadtree.getMPLRectangles()
            for r in rects:
                r.set_edgecolor((.4, .4, .4))
                r.set_linewidth(.5)
                r.set_facecolor('none')
                r.set_x(r.get_x() - offset_e)
                r.set_y(r.get_y() - offset_n)
            map(ax.add_artist, rects)

            if self.show_leaf_centres:
                ax.scatter(scene.quadtree.leaf_coordinates[:, 0] - offset_e,
                           scene.quadtree.leaf_coordinates[:, 1] - offset_n,
                           s=.25, c='black', alpha=.1)

        def add_arrow(ax, scene):
            phi = num.nanmean(scene.phi)
            los_dx = num.cos(phi + num.pi) * .0625
            los_dy = num.sin(phi + num.pi) * .0625

            az_dx = num.cos(phi - num.pi/2) * .125
            az_dy = num.sin(phi - num.pi/2) * .125

            anchor_x = .9 if los_dx < 0 else .1
            anchor_y = .85 if los_dx < 0 else .975

            az_arrow = patches.FancyArrow(
                x=anchor_x-az_dx, y=anchor_y-az_dy,
                dx=az_dx, dy=az_dy,
                head_width=.025,
                alpha=.5, fc='k',
                head_starts_at_zero=False,
                length_includes_head=True,
                transform=ax.transAxes)

            los_arrow = patches.FancyArrow(
                x=anchor_x-az_dx/2, y=anchor_y-az_dy/2,
                dx=los_dx, dy=los_dy,
                head_width=.02,
                alpha=.5, fc='k',
                head_starts_at_zero=False,
                length_includes_head=True,
                transform=ax.transAxes)

            ax.add_artist(az_arrow)
            ax.add_artist(los_arrow)

        urE, urN, llE, llN = (0., 0., 0., 0.)
        for target in sat_targets:

            if target.scene.frame.isMeter():
                off_n, off_e = map(float, latlon_to_ne_numpy(
                    target.scene.frame.llLat, target.scene.frame.llLon,
                    source.effective_lat, source.effective_lon))
            if target.scene.frame.isDegree():
                off_n = source.effective_lat - target.scene.frame.llLat
                off_e = source.effective_lon - target.scene.frame.llLon

            turE, turN, tllE, tllN = zip(
                *[(leaf.gridE.max()-off_e,
                   leaf.gridN.max()-off_n,
                   leaf.gridE.min()-off_e,
                   leaf.gridN.min()-off_n)
                  for leaf in target.scene.quadtree.leaves])

            turE, turN = map(max, (turE, turN))
            tllE, tllN = map(min, (tllE, tllN))
            urE, urN = map(max, ((turE, urE), (urN, turN)))
            llE, llN = map(min, ((tllE, llE), (llN, tllN)))

        def generate_plot(sat_target, result, ifig):

            scene = sat_target.scene

            fig = plt.figure()
            fig.set_size_inches(*self.size_inch)
            gs = gridspec.GridSpec(
                2, 3,
                wspace=.15, hspace=.2,
                left=.1, right=.975, top=.95,
                height_ratios=[12, 1])

            item = PlotItem(
                name='fig_%i' % ifig,
                attributes={'targets': [sat_target.path]},
                title=u'Satellite Surface Displacements - %s'
                      % scene.meta.scene_title,
                description=u'''
Surface displacements derived from satellite data.
(Left) the input data, (center) the modelled
data and (right) the model residual.
''')

            stat_obs = result.statics_obs['displacement.los']
            stat_syn = result.statics_syn['displacement.los']
            res = stat_obs - stat_syn

            if scene.frame.isMeter():
                offset_n, offset_e = map(float, latlon_to_ne_numpy(
                    scene.frame.llLat, scene.frame.llLon,
                    source.effective_lat, source.effective_lon))
            elif scene.frame.isDegree():
                offset_n = source.effective_lat - scene.frame.llLat
                offset_e = source.effective_lon - scene.frame.llLon

            im_extent = (
                scene.frame.E.min() - offset_e,
                scene.frame.E.max() - offset_e,
                scene.frame.N.min() - offset_n,
                scene.frame.N.max() - offset_n)

            if self.displacement_unit == 'rad':
                wavelength = scene.meta.wavelength
                if wavelength is None:
                    raise AttributeError(
                        'The satellite\'s wavelength is not set')

                stat_obs = displ2rad(stat_obs, wavelength)
                stat_syn = displ2rad(stat_syn, wavelength)
                res = displ2rad(res, wavelength)

                self.colormap = 'hsv'
                data_range = (0., num.pi)

            else:
                abs_displ = num.abs([stat_obs.min(), stat_obs.max(),
                                     stat_syn.min(), stat_syn.max(),
                                     res.min(), res.max()]).max()
                data_range = (-abs_displ, abs_displ)

            cmw = cm.ScalarMappable(cmap=self.colormap)
            cmw.set_clim(*data_range)
            cmw.set_array(stat_obs)

            axes = [fig.add_subplot(gs[0, 0]),
                    fig.add_subplot(gs[0, 1]),
                    fig.add_subplot(gs[0, 2])]

            ax = axes[0]
            ax.imshow(
                get_displacement_rgba(stat_obs, scene, cmw),
                extent=im_extent, origin='lower')
            draw_leaves(ax, scene, offset_e, offset_n)
            draw_source(ax, scene)
            add_arrow(ax, scene)
            init_axes(ax, scene, 'Observed')

            ax.text(.025, .025, 'Scene ID: %s' % scene.meta.scene_id,
                    fontsize=8, alpha=.7,
                    va='bottom', transform=ax.transAxes)
            if scene.frame.isMeter():
                ax.set_ylabel('Northing [km]', fontsize=self.font_size)

            ax = axes[1]
            ax.imshow(
                get_displacement_rgba(stat_syn, scene, cmw),
                extent=im_extent, origin='lower')
            draw_leaves(ax, scene, offset_e, offset_n)
            draw_source(ax, scene)
            add_arrow(ax, scene)
            init_axes(ax, scene, 'Model')
            ax.get_yaxis().set_visible(False)

            ax = axes[2]
            ax.imshow(
                get_displacement_rgba(res, scene, cmw),
                extent=im_extent, origin='lower')

            draw_leaves(ax, scene, offset_e, offset_n)
            draw_source(ax, scene)
            add_arrow(ax, scene)
            init_axes(ax, scene, 'Residual', last_axes=True)
            ax.get_yaxis().set_visible(False)

            for ax in axes:
                ax.set_xlim(*im_extent[:2])
                ax.set_ylim(*im_extent[2:])

            if closeup:
                if scene.frame.isMeter():
                    fn, fe = source.outline(cs='xy').T
                elif scene.frame.isDegree():
                    fn, fe = source.outline(cs='latlon').T
                    fn -= source.effective_lat
                    fe -= source.effective_lon

                if fn.size > 1:
                    off_n = (fn[0] + fn[1]) / 2
                    off_e = (fe[0] + fe[1]) / 2
                else:
                    off_n = fn[0]
                    off_e = fe[0]

                fault_size = 2*num.sqrt(max(abs(fn-off_n))**2
                                        + max(abs(fe-off_e))**2)
                fault_size *= self.map_scale
                if fault_size == 0.0:
                    extent = (scene.frame.N[-1] + scene.frame.E[-1]) / 2
                    fault_size = extent * .25

                for ax in axes:
                    ax.set_xlim(-fault_size/2 + off_e, fault_size/2 + off_e)
                    ax.set_ylim(-fault_size/2 + off_n, fault_size/2 + off_n)

            if self.map_limits is not None:
                xmin, xmax, ymin, ymax = self.map_limits
                assert xmin < xmax, 'bad map_limits xmin > xmax'
                assert ymin < ymax, 'bad map_limits ymin > ymax'

                for ax in axes:
                    ax.set_xlim(
                        xmin/ax.scale_x['scale'] - ax.scale_x['offset'],
                        xmax/ax.scale_x['scale'] - ax.scale_x['offset'],)
                    ax.set_ylim(
                        ymin/ax.scale_y['scale'] - ax.scale_y['offset'],
                        ymax/ax.scale_y['scale'] - ax.scale_y['offset'])

            if self.displacement_unit == 'm':
                def cfmt(x, p):
                    return '%.2f' % x
            elif self.displacement_unit == 'cm':
                def cfmt(x, p):
                    return '%.1f' % (x * 1e2)
            elif self.displacement_unit == 'mm':
                def cfmt(x, p):
                    return '%.0f' % (x * 1e3)
            elif self.displacement_unit == 'rad':
                def cfmt(x, p):
                    return '%.2f' % x
            else:
                raise AttributeError(
                    'unknown displacement unit %s' % self.displacement_unit)

            cbar_args = dict(
                orientation='horizontal',
                format=FuncFormatter(cfmt),
                use_gridspec=True)
            cbar_label = 'LOS Displacement [%s]' % self.displacement_unit

            if self.common_color_scale:
                cax = fig.add_subplot(gs[1, 1])
                cax.set_aspect(.05)
                cbar = fig.colorbar(cmw, cax=cax, **cbar_args)
                cbar.set_label(cbar_label)
            else:
                for idata, data in enumerate((stat_syn, stat_obs, res)):
                    cax = fig.add_subplot(gs[1, idata])
                    cax.set_aspect(.05)

                    if not self.displacement_unit == 'rad':
                        abs_displ = num.abs(data).max()
                        cmw.set_clim(-abs_displ, abs_displ)

                    cbar = fig.colorbar(cmw, cax=cax, **cbar_args)
                    cbar.set_label(cbar_label)

            return (item, fig)

        for ifig, (sat_target, result) in enumerate(zip(sat_targets, results)):
            yield generate_plot(sat_target, result, ifig)
Example #29
0
    def process(self,
                event,
                timing,
                bazi=None,
                slow=None,
                restitute=False,
                *args,
                **kwargs):
        '''
      :param timing: CakeTiming. Uses the definition without the offset.
      :param fn_dump_center: filename to where center stations shall be dumped
      :param fn_beam: filename of beam trace
      :param model: earthmodel to use(optional)
      :param earthmodel to use(optional)
      :param network: network code(optional)
      :param station: station code(optional)
        '''
        logger.debug('start beam forming')
        stations = self.stations
        network_code = kwargs.get('responses', None)
        network_code = kwargs.get('network', '')
        station_code = kwargs.get('station', 'STK')
        c_station_id = (network_code, station_code)
        t_shifts = []
        lat_c, lon_c, z_c = self.c_lat_lon_z

        self.station_c = Station(lat=float(lat_c),
                                 lon=float(lon_c),
                                 elevation=float(z_c),
                                 depth=0.,
                                 name='Array Center',
                                 network=c_station_id[0],
                                 station=c_station_id[1][:5])
        fn_dump_center = kwargs.get('fn_dump_center', 'array_center.pf')
        fn_beam = kwargs.get('fn_beam', 'beam.mseed')
        if event:
            mod = cake.load_model(crust2_profile=(event.lat, event.lon))
            dist = ortho.distance_accurate50m(event, self.station_c)
            ray = timing.t(mod, (event.depth, dist), get_ray=True)

            if ray is None:
                logger.error(
                    'None of defined phases available at beam station:\n %s' %
                    self.station_c)
                return
            else:
                b = ortho.azimuth(self.station_c, event)
                if b >= 0.:
                    self.bazi = b
                elif b < 0.:
                    self.bazi = 360. + b
                self.slow = ray.p / (cake.r2d * cake.d2m)
        else:
            self.bazi = bazi
            self.slow = slow

        logger.info(
            'stacking %s with slowness %1.4f s/km at back azimut %1.1f '
            'degrees' %
            ('.'.join(c_station_id), self.slow * cake.km, self.bazi))

        lat0 = num.array([lat_c] * len(stations))
        lon0 = num.array([lon_c] * len(stations))
        lats = num.array([s.lat for s in stations])
        lons = num.array([s.lon for s in stations])
        ns, es = ortho.latlon_to_ne_numpy(lat0, lon0, lats, lons)
        theta = num.float(self.bazi * num.pi / 180.)
        R = num.array([[num.cos(theta), -num.sin(theta)],
                       [num.sin(theta), num.cos(theta)]])
        distances = R.dot(num.vstack((es, ns)))[1]
        channels = set()
        self.stacked = {}
        num_stacked = {}
        self.t_shifts = {}
        self.shifted_traces = []
        taperer = trace.CosFader(xfrac=0.05)
        if self.diff_dt_treat == 'downsample':
            self.traces.sort(key=lambda x: x.deltat)
        elif self.diff_dt_treat == 'oversample':
            dts = [t.deltat for t in self.traces]
            for tr in self.traces:
                tr.resample(min(dts))

        for tr in self.traces:
            if tr.nslc_id[:2] == c_station_id:
                continue
            tr = tr.copy(data=True)
            tr.ydata = tr.ydata.astype(
                num.float64) - tr.ydata.mean(dtype=num.float64)
            tr.taper(taperer)
            try:
                stack_trace = self.stacked[tr.channel]
                num_stacked[tr.channel] += 1
            except KeyError:
                stack_trace = tr.copy(data=True)
                stack_trace.set_ydata(num.zeros(len(stack_trace.get_ydata())))

                stack_trace.set_codes(network=c_station_id[0],
                                      station=c_station_id[1],
                                      location='',
                                      channel=tr.channel)

                self.stacked[tr.channel] = stack_trace
                channels.add(tr.channel)
                num_stacked[tr.channel] = 1

            nslc_id = tr.nslc_id

            try:
                stats = list(
                    filter(
                        lambda x: util.match_nslc('%s.%s.%s.*' % x.nsl(),
                                                  nslc_id), stations))
                stat = stats[0]
            except IndexError:
                break

            i = stations.index(stat)
            d = distances[i]
            t_shift = d * self.slow
            t_shifts.append(t_shift)
            tr.shift(t_shift)
            self.t_shifts[tr.nslc_id[:2]] = t_shift
            if self.normalize_std:
                tr.ydata = tr.ydata / tr.ydata.std()

            if num.abs(tr.deltat - stack_trace.deltat) > 0.000001:
                if self.diff_dt_treat == 'downsample':
                    stack_trace.downsample_to(tr.deltat)
                elif self.diff_dt_treat == 'upsample':
                    raise Exception(
                        'something went wrong with the upsampling, previously')
            stack_trace.add(tr)
            self.shifted_traces.append(tr)

        if self.post_normalize:
            for ch, tr in self.stacked.items():
                tr.set_ydata(tr.get_ydata() / num_stacked[ch])

        self.save_station(fn_dump_center)
        self.checked_nslc([stack_trace])
        self.save(stack_trace, fn_beam)
        return self.shifted_traces, stack_trace, t_shifts
    def call(self):
        self.cleanup()
        c_station_id = ('_', 'STK')
        if self.unit == 's/deg':
            slow_factor = 1. / onedeg
        elif self.unit == 's/km':
            slow_factor = 1. / 1000.

        slow = self.slow * slow_factor
        if self.stacked_traces is not None:
            self.add_traces(self.stacked_traces)
        viewer = self.get_viewer()
        if self.station_c:
            viewer.stations.pop(c_station_id)

        stations = self.get_stations()
        if len(stations) == 0:
            self.fail('No station meta information found')

        traces = list(self.chopper_selected_traces(fallback=True))
        traces = [tr for trs in traces for tr in trs]
        visible_nslcs = [tr.nslc_id for tr in traces]
        stations = [
            x for x in stations
            if util.match_nslcs("%s.%s.%s.*" % x.nsl(), visible_nslcs)
        ]
        if not self.lat_c or not self.lon_c or not self.z_c:
            self.lat_c, self.lon_c, self.z_c = self.center_lat_lon(stations)
            self.set_parameter('lat_c', self.lat_c)
            self.set_parameter('lon_c', self.lon_c)

        self.station_c = Station(lat=float(self.lat_c),
                                 lon=float(self.lon_c),
                                 elevation=float(self.z_c),
                                 depth=0.,
                                 name='Array Center',
                                 network=c_station_id[0],
                                 station=c_station_id[1])

        viewer.add_stations([self.station_c])
        lat0 = num.array([self.lat_c] * len(stations))
        lon0 = num.array([self.lon_c] * len(stations))
        lats = num.array([s.lat for s in stations])
        lons = num.array([s.lon for s in stations])
        ns, es = ortho.latlon_to_ne_numpy(lat0, lon0, lats, lons)
        theta = num.float(self.bazi * num.pi / 180.)
        R = num.array([[num.cos(theta), -num.sin(theta)],
                       [num.sin(theta), num.cos(theta)]])
        distances = R.dot(num.vstack((es, ns)))[1]
        channels = set()
        self.stacked = {}
        num_stacked = {}
        self.t_shifts = {}
        shifted_traces = []
        taperer = trace.CosFader(xfrac=0.05)
        if self.diff_dt_treat == 'downsample':
            traces.sort(key=lambda x: x.deltat)
        elif self.diff_dt_treat == 'oversample':
            dts = [t.deltat for t in traces]
            for tr in traces:
                tr.resample(min(dts))

        for tr in traces:
            if tr.nslc_id[:2] == c_station_id:
                continue
            tr = tr.copy(data=True)
            tr.ydata = tr.ydata.astype(num.float64)
            tr.ydata -= tr.ydata.mean(dtype=num.float64)
            tr.taper(taperer)
            try:
                stack_trace = self.stacked[tr.channel]
                num_stacked[tr.channel] += 1
            except KeyError:
                stack_trace = tr.copy(data=True)
                stack_trace.set_ydata(num.zeros(len(stack_trace.get_ydata())))

                stack_trace.set_codes(network=c_station_id[0],
                                      station=c_station_id[1],
                                      location='',
                                      channel=tr.channel)

                self.stacked[tr.channel] = stack_trace
                channels.add(tr.channel)
                num_stacked[tr.channel] = 1

            nslc_id = tr.nslc_id

            try:
                stats = [
                    x for x in stations
                    if util.match_nslc('%s.%s.%s.*' % x.nsl(), nslc_id)
                ]

                stat = stats[0]
            except IndexError:
                break

            i = stations.index(stat)
            d = distances[i]
            t_shift = d * slow
            tr.shift(t_shift)
            stat = viewer.get_station(tr.nslc_id[:2])
            self.t_shifts[stat] = t_shift
            if self.normalize_std:
                tr.ydata = tr.ydata / tr.ydata.std()

            if num.abs(tr.deltat - stack_trace.deltat) > 0.000001:
                if self.diff_dt_treat == 'downsample':
                    stack_trace.downsample_to(tr.deltat)
                elif self.diff_dt_treat == 'upsample':
                    print(
                        'something went wrong with the upsampling, previously')
            stack_trace.add(tr)

            if self.add_shifted:
                tr.set_station('%s_s' % tr.station)
                shifted_traces.append(tr)

        if self.post_normalize:
            for ch, tr in self.stacked.items():
                tr.set_ydata(tr.get_ydata() / num_stacked[ch])

        self.cleanup()

        for ch, tr in self.stacked.items():
            if num_stacked[ch] > 1:
                self.add_trace(tr)

        if self.add_shifted:
            self.add_traces(shifted_traces)
    def process(self, event, timing, bazi=None, slow=None,  restitute=False, *args, **kwargs):
        '''
        :param timing: CakeTiming. Uses the definition without the offset.
        :param fn_dump_center: filename to where center stations shall be dumped
        :param fn_beam: filename of beam trace
        :param model: earthmodel to use (optional)
        :param earthmodel to use (optional)
        :param network: network code (optional)
        :param station: station code (optional)
        '''
        logger.debug('start beam forming')
        stations = self.stations
        network_code = kwargs.get('responses', None)
        network_code = kwargs.get('network', '')
        station_code = kwargs.get('station', 'STK')
        c_station_id = (network_code, station_code)

        lat_c, lon_c, z_c = self.c_lat_lon_z

        self.station_c = Station(lat=float(lat_c),
                                 lon=float(lon_c),
                                 elevation=float(z_c),
                                 depth=0.,
                                 name='Array Center',
                                 network=c_station_id[0],
                                 station=c_station_id[1][:5])
        fn_dump_center = kwargs.get('fn_dump_center', 'array_center.pf')
        fn_beam = kwargs.get('fn_beam', 'beam.mseed')
        if event:
            mod = cake.load_model(crust2_profile=(event.lat, event.lon))
            dist = ortho.distance_accurate50m(event, self.station_c)
            ray = timing.t(mod, (event.depth, dist), get_ray=True)
            if ray is None:
                logger.error('None of defined phases available at beam station:\n %s' % self.station_c)
                return
            else:
                b = ortho.azimuth(self.station_c, event)
                if b>=0.:
                    self.bazi = b
                elif b<0.:
                    self.bazi = 360.+b
                self.slow = ray.p/(cake.r2d*cake.d2m)
        else:
            self.bazi = bazi
            self.slow = slow

        logger.info('stacking %s with slowness %1.4f s/km at back azimut %1.1f '
                    'degrees' %('.'.join(c_station_id), self.slow*cake.km, self.bazi))

        lat0 = num.array([lat_c]*len(stations))
        lon0 = num.array([lon_c]*len(stations))
        lats = num.array([s.lat for s in stations])
        lons = num.array([s.lon for s in stations])
        ns, es = ortho.latlon_to_ne_numpy(lat0, lon0, lats, lons)
        theta = num.float(self.bazi*num.pi/180.)
        R = num.array([[num.cos(theta), -num.sin(theta)],
                        [num.sin(theta), num.cos(theta)]])
        distances = R.dot(num.vstack((es, ns)))[1]
        channels = set()
        self.stacked = {}
        num_stacked = {}
        self.t_shifts = {}
        self.shifted_traces = []
        taperer = trace.CosFader(xfrac=0.05)
        if self.diff_dt_treat=='downsample':
            self.traces.sort(key=lambda x: x.deltat)
        elif self.diff_dt_treat=='oversample':
            dts = [t.deltat for t in self.traces]
            for tr in self.traces:
                tr.resample(min(dts))

        for tr in self.traces:
            if tr.nslc_id[:2] == c_station_id:
                continue
            tr = tr.copy(data=True)
            tr.ydata = tr.ydata.astype(num.float64) - tr.ydata.mean(dtype=num.float64)
            tr.taper(taperer)
            try:
                stack_trace = self.stacked[tr.channel]
                num_stacked[tr.channel] += 1
            except KeyError:
                stack_trace = tr.copy(data=True)
                stack_trace.set_ydata(num.zeros(
                    len(stack_trace.get_ydata())))

                stack_trace.set_codes(network=c_station_id[0],
                                      station=c_station_id[1],
                                      location='',
                                      channel=tr.channel)

                self.stacked[tr.channel] = stack_trace
                channels.add(tr.channel)
                num_stacked[tr.channel] = 1

            nslc_id = tr.nslc_id

            try:
                stats = filter(lambda x: util.match_nslc(
                    '%s.%s.%s.*' % x.nsl(), nslc_id), stations)

                stat = stats[0]
            except IndexError:
                break

            i = stations.index(stat)
            d = distances[i]
            t_shift = d*self.slow
            tr.shift(t_shift)
            #stat = viewer.get_station(tr.nslc_id[:2])
            self.t_shifts[tr.nslc_id[:2]] = t_shift
            if self.normalize_std:
                tr.ydata = tr.ydata/tr.ydata.std()

            if num.abs(tr.deltat-stack_trace.deltat)>0.000001:
                if self.diff_dt_treat=='downsample':
                    stack_trace.downsample_to(tr.deltat)
                elif self.diff_dt_treat=='upsample':
                    raise Exception('something went wrong with the upsampling, previously')
            stack_trace.add(tr)

            tr.set_station('%s_s' % tr.station)
            self.shifted_traces.append(tr)

        if self.post_normalize:
            for ch, tr in self.stacked.items():
                tr.set_ydata(tr.get_ydata()/num_stacked[ch])
        #for ch, tr in self.stacked.items():
        #    if num_stacked[ch]>1:
        #        self.add_trace(tr)
        self.save_station(fn_dump_center)
        self.checked_nslc([stack_trace])
        self.save(stack_trace, fn_beam)
Example #32
0
        def generate_plot(sat_target, result, ifig):

            scene = sat_target.scene

            fig = plt.figure()
            fig.set_size_inches(*self.size_inch)
            gs = gridspec.GridSpec(
                2, 3,
                wspace=.15, hspace=.2,
                left=.1, right=.975, top=.95,
                height_ratios=[12, 1])

            item = PlotItem(
                name='fig_%i' % ifig,
                attributes={'targets': [sat_target.path]},
                title=u'Satellite Surface Displacements - %s'
                      % scene.meta.scene_title,
                description=u'''
Surface displacements derived from satellite data.
(Left) the input data, (center) the modelled
data and (right) the model residual.
''')

            stat_obs = result.statics_obs['displacement.los']
            stat_syn = result.statics_syn['displacement.los']
            res = stat_obs - stat_syn

            if scene.frame.isMeter():
                offset_n, offset_e = map(float, latlon_to_ne_numpy(
                    scene.frame.llLat, scene.frame.llLon,
                    source.effective_lat, source.effective_lon))
            elif scene.frame.isDegree():
                offset_n = source.effective_lat - scene.frame.llLat
                offset_e = source.effective_lon - scene.frame.llLon

            im_extent = (
                scene.frame.E.min() - offset_e,
                scene.frame.E.max() - offset_e,
                scene.frame.N.min() - offset_n,
                scene.frame.N.max() - offset_n)

            if self.displacement_unit == 'rad':
                wavelength = scene.meta.wavelength
                if wavelength is None:
                    raise AttributeError(
                        'The satellite\'s wavelength is not set')

                stat_obs = displ2rad(stat_obs, wavelength)
                stat_syn = displ2rad(stat_syn, wavelength)
                res = displ2rad(res, wavelength)

                self.colormap = 'hsv'
                data_range = (0., num.pi)

            else:
                abs_displ = num.abs([stat_obs.min(), stat_obs.max(),
                                     stat_syn.min(), stat_syn.max(),
                                     res.min(), res.max()]).max()
                data_range = (-abs_displ, abs_displ)

            cmw = cm.ScalarMappable(cmap=self.colormap)
            cmw.set_clim(*data_range)
            cmw.set_array(stat_obs)

            axes = [fig.add_subplot(gs[0, 0]),
                    fig.add_subplot(gs[0, 1]),
                    fig.add_subplot(gs[0, 2])]

            ax = axes[0]
            ax.imshow(
                get_displacement_rgba(stat_obs, scene, cmw),
                extent=im_extent, origin='lower')
            draw_leaves(ax, scene, offset_e, offset_n)
            draw_source(ax, scene)
            add_arrow(ax, scene)
            init_axes(ax, scene, 'Observed')

            ax.text(.025, .025, 'Scene ID: %s' % scene.meta.scene_id,
                    fontsize=8, alpha=.7,
                    va='bottom', transform=ax.transAxes)
            if scene.frame.isMeter():
                ax.set_ylabel('Northing [km]', fontsize=self.font_size)

            ax = axes[1]
            ax.imshow(
                get_displacement_rgba(stat_syn, scene, cmw),
                extent=im_extent, origin='lower')
            draw_leaves(ax, scene, offset_e, offset_n)
            draw_source(ax, scene)
            add_arrow(ax, scene)
            init_axes(ax, scene, 'Model')
            ax.get_yaxis().set_visible(False)

            ax = axes[2]
            ax.imshow(
                get_displacement_rgba(res, scene, cmw),
                extent=im_extent, origin='lower')

            draw_leaves(ax, scene, offset_e, offset_n)
            draw_source(ax, scene)
            add_arrow(ax, scene)
            init_axes(ax, scene, 'Residual', last_axes=True)
            ax.get_yaxis().set_visible(False)

            for ax in axes:
                ax.set_xlim(*im_extent[:2])
                ax.set_ylim(*im_extent[2:])

            if closeup:
                if scene.frame.isMeter():
                    fn, fe = source.outline(cs='xy').T
                elif scene.frame.isDegree():
                    fn, fe = source.outline(cs='latlon').T
                    fn -= source.effective_lat
                    fe -= source.effective_lon

                if fn.size > 1:
                    off_n = (fn[0] + fn[1]) / 2
                    off_e = (fe[0] + fe[1]) / 2
                else:
                    off_n = fn[0]
                    off_e = fe[0]

                fault_size = 2*num.sqrt(max(abs(fn-off_n))**2
                                        + max(abs(fe-off_e))**2)
                fault_size *= self.map_scale
                if fault_size == 0.0:
                    extent = (scene.frame.N[-1] + scene.frame.E[-1]) / 2
                    fault_size = extent * .25

                for ax in axes:
                    ax.set_xlim(-fault_size/2 + off_e, fault_size/2 + off_e)
                    ax.set_ylim(-fault_size/2 + off_n, fault_size/2 + off_n)

            if self.map_limits is not None:
                xmin, xmax, ymin, ymax = self.map_limits
                assert xmin < xmax, 'bad map_limits xmin > xmax'
                assert ymin < ymax, 'bad map_limits ymin > ymax'

                for ax in axes:
                    ax.set_xlim(
                        xmin/ax.scale_x['scale'] - ax.scale_x['offset'],
                        xmax/ax.scale_x['scale'] - ax.scale_x['offset'],)
                    ax.set_ylim(
                        ymin/ax.scale_y['scale'] - ax.scale_y['offset'],
                        ymax/ax.scale_y['scale'] - ax.scale_y['offset'])

            if self.displacement_unit == 'm':
                def cfmt(x, p):
                    return '%.2f' % x
            elif self.displacement_unit == 'cm':
                def cfmt(x, p):
                    return '%.1f' % (x * 1e2)
            elif self.displacement_unit == 'mm':
                def cfmt(x, p):
                    return '%.0f' % (x * 1e3)
            elif self.displacement_unit == 'rad':
                def cfmt(x, p):
                    return '%.2f' % x
            else:
                raise AttributeError(
                    'unknown displacement unit %s' % self.displacement_unit)

            cbar_args = dict(
                orientation='horizontal',
                format=FuncFormatter(cfmt),
                use_gridspec=True)
            cbar_label = 'LOS Displacement [%s]' % self.displacement_unit

            if self.common_color_scale:
                cax = fig.add_subplot(gs[1, 1])
                cax.set_aspect(.05)
                cbar = fig.colorbar(cmw, cax=cax, **cbar_args)
                cbar.set_label(cbar_label)
            else:
                for idata, data in enumerate((stat_syn, stat_obs, res)):
                    cax = fig.add_subplot(gs[1, idata])
                    cax.set_aspect(.05)

                    if not self.displacement_unit == 'rad':
                        abs_displ = num.abs(data).max()
                        cmw.set_clim(-abs_displ, abs_displ)

                    cbar = fig.colorbar(cmw, cax=cax, **cbar_args)
                    cbar.set_label(cbar_label)

            return (item, fig)
Example #33
0
    def call(self):

        self.cleanup()
        if self.stacked_traces is not None:
            self.add_traces(self.stacked_traces)
        viewer = self.get_viewer()
        if self.station_c:
            viewer.stations.pop(('', 'STK'))

        stations = self.get_stations()

        if not self.lat_c or not self.lon_c or not self.z_c:
            self.lat_c, self.lon_c, self.z_c = self.center_lat_lon(stations)
            self.set_parameter('lat_c', self.lat_c)
            self.set_parameter('lon_c', self.lon_c)

        self.station_c = Station(lat=float(self.lat_c),
                                 lon=float(self.lon_c),
                                 elevation=float(self.z_c),
                                 depth=0.,
                                 name='Array Center',
                                 network='',
                                 station='STK')

        viewer.add_stations([self.station_c])
        lat0 = num.array([self.lat_c]*len(stations))
        lon0 = num.array([self.lon_c]*len(stations))
        lats = num.array([s.lat for s in stations])
        lons = num.array([s.lon for s in stations])
        ns, es = ortho.latlon_to_ne_numpy(lat0, lon0, lats, lons)
        theta = num.float(self.bazi*num.pi/180.)
        R = num.array([[num.cos(theta), -num.sin(theta)],
                        [num.sin(theta), num.cos(theta)]])
        distances = R.dot(num.vstack((es, ns)))[1]
        channels = set()
        self.stacked = {}
        num_stacked = {}
        self.t_shifts = {}
        shifted_traces = []
        traces = list(self.chopper_selected_traces(fallback=True))
        traces = [tr for trs in traces for tr in trs ]
        taperer = trace.CosFader(xfrac=0.05)
        if self.diff_dt_treat=='downsample':
            traces.sort(key=lambda x: x.deltat)
        elif self.diff_dt_treat=='oversample':
            dts = [t.deltat for t in traces]
            for tr in traces:
                tr.resample(min(dts))

        for tr in traces:
            if tr.nslc_id[:3] == ('_', 'STK', ''):
                continue
            tr = tr.copy(data=True)
            tr.ydata = tr.ydata.astype(num.float64)
            tr.ydata -= tr.ydata.mean(dtype=num.float64)
            tr.taper(taperer)
            try:
                stack_trace = self.stacked[tr.channel]
                num_stacked[tr.channel] += 1
            except KeyError:
                stack_trace = tr.copy(data=True)
                stack_trace.set_ydata(num.zeros(
                    len(stack_trace.get_ydata())))

                stack_trace.set_codes(network='_',
                                      station='STK',
                                      location='',
                                      channel=tr.channel)

                self.stacked[tr.channel] = stack_trace
                channels.add(tr.channel)
                num_stacked[tr.channel] = 1

            nslc_id = tr.nslc_id

            try:
                stats = filter(lambda x: util.match_nslc(
                    '%s.%s.%s.*' % x.nsl(), nslc_id), stations)

                stat = stats[0]
            except IndexError:
                break

            i = stations.index(stat)
            d = distances[i]
            t_shift = d*self.slow/1000.
            tr.shift(t_shift)
            stat = viewer.get_station(tr.nslc_id[:2])
            self.t_shifts[stat] = t_shift
            if self.normalize_std:
                tr.ydata = tr.ydata/tr.ydata.std()

            if num.abs(tr.deltat-stack_trace.deltat)>0.000001:
                if self.diff_dt_treat=='downsample':
                    stack_trace.downsample_to(tr.deltat)
                elif self.diff_dt_treat=='upsample':
                    print 'something went wrong with the upsampling, previously'
            stack_trace.add(tr)

            if self.add_shifted:
                tr.set_station('%s_s' % tr.station)
                shifted_traces.append(tr)

        if self.post_normalize:
            for ch, tr in self.stacked.items():
                tr.set_ydata(tr.get_ydata()/num_stacked[ch])
        self.stacked_traces = self.stacked.values()
        self.cleanup()
        self.add_traces(self.stacked_traces)
        if self.add_shifted:
            self.add_traces(shifted_traces)
Example #34
0
import numpy as num
from pyrocko import topo, plot, orthodrome as od

lon_min, lon_max, lat_min, lat_max = 14.34, 14.50, 40.77, 40.87
dem_name = 'SRTMGL3'

# extract gridded topography (possibly downloading first)
tile = topo.get(dem_name, (lon_min, lon_max, lat_min, lat_max))

# geographic to local cartesian coordinates
lons = tile.x()
lats = tile.y()
lons2 = num.tile(lons, lats.size)
lats2 = num.repeat(lats, lons.size)
norths, easts = od.latlon_to_ne_numpy(lats[0], lons[0], lats2, lons2)
norths = norths.reshape((lats.size, lons.size))
easts = easts.reshape((lats.size, lons.size))

# plot it
plt = plot.mpl_init(fontsize=10.)
fig = plt.figure(figsize=plot.mpl_papersize('a5', 'landscape'))
axes = fig.add_subplot(1, 1, 1, aspect=1.0)
cbar  = axes.pcolormesh(easts, norths, tile.data,
                        cmap='gray', shading='gouraud')
fig.colorbar(cbar, label='Altitude [m]')
axes.set_title(dem_name)
axes.set_xlim(easts.min(), easts.max())
axes.set_ylim(norths.min(), norths.max())
axes.set_xlabel('Easting [m]')
axes.set_ylabel('Northing [m]')
fig.savefig('topo_example.png')
Example #35
0
def get_scenario(engine, source, store_id, extent=30, ngrid=40, stations=None):
    '''
    Setup scenario with source model, STF and a rectangular grid of targets.
    '''

    # physical grid size in [m]
    grid_extent = extent * km
    lat, lon = source.lat, source.lon
    # number of grid points
    nnorth = neast = ngrid
    try:
        stf_spec = BruneResponse(duration=source.duration)
    except AttributeError:
        stf_spec = BruneResponse(duration=0.5)
    store = engine.get_store(store_id)

    if stations is None:
        # receiver grid
        r = grid_extent / 2.0

        norths = num.linspace(-r, r, nnorth)
        easts = num.linspace(-r, r, neast)
        norths2, easts2 = coords_2d(norths, easts)
        targets = []
        for i in range(norths2.size):

            for component in 'ZNE':
                target = gf.Target(quantity='displacement',
                                   codes=('', '%04i' % i, '', component),
                                   lat=lat,
                                   lon=lon,
                                   north_shift=float(norths2[i]),
                                   east_shift=float(easts2[i]),
                                   store_id=store_id,
                                   interpolation='nearest_neighbor')
                # in case we have not calculated GFs for zero distance
                if source.distance_to(target) >= store.config.distance_min:
                    targets.append(target)
    else:
        targets = []
        norths = []
        easts = []
        # here maybe use common ne frame?
        for i, st in enumerate(stations):
            north, east = orthodrome.latlon_to_ne_numpy(
                lat,
                lon,
                st.lat,
                st.lon,
            )
            norths.append(north[0])
            easts.append(east[0])
            norths2, easts2 = coords_2d(north, east)

            for cha in st.channels:
                target = gf.Target(quantity='displacement',
                                   codes=(str(st.network), i, str(st.location),
                                          str(cha.name)),
                                   lat=lat,
                                   lon=lon,
                                   north_shift=float(norths2),
                                   east_shift=float(easts2),
                                   store_id=store_id,
                                   interpolation='nearest_neighbor')
                # in case we have not calculated GFs for zero distance
                if source.distance_to(target) >= store.config.distance_min:
                    targets.append(target)
        norths = num.asarray(norths)
        easts = num.asarray(easts)
    return targets, norths, easts, stf_spec