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))
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)
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
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))
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.)
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
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
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
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
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
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
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
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)
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
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
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
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
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()
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)
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)
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()
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)
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)
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)
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)
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')
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