def dEmeter(self): if self.isMeter(): return self.dE else: _, dEmeter = latlon_to_ne(self.llLat, self.llLon, self.llLat, self.llLon + self.dE) return dEmeter
def dNmeter(self): if self.isMeter(): return self.dN else: dNmeter, _ = latlon_to_ne(self.llLat, self.llLon, self.llLat + self.dN, self.llLon) return dNmeter
def dEmeter(self): if self.isMeter(): return self.dE _, dEmeter = latlon_to_ne(self.llLat, self.llLon, self.llLat, self.llLon + self.dE * self.cols) return dEmeter / self.cols
def dNmeter(self): if self.isMeter(): return self.dN dNmeter, _ = latlon_to_ne( self.llLat, self.llLon, self.llLat + self.dN * self.rows, self.llLon ) return dNmeter / self.rows
def extract_labels(self, marker): if not self.labeled: return UNLABELED source = marker.get_event() n, e = orthodrome.latlon_to_ne( self.config.reference_target.lat, self.config.reference_target.lon, source.lat, source.lon) return (n, e, source.depth)
def to_cartesian(items): res = [] latlon00 = ortho.Loc(0.,0.) for i, item in enumerate(items): y, x = ortho.latlon_to_ne(latlon00, item) depth = item.depth lat = item.lat/180.*num.pi res.append((x, y, -depth)) return res
def to_cartesian(items, reflatlon): res = defaultdict() for i, item in enumerate(items): y, x = ortho.latlon_to_ne(reflatlon, item) depth = item.depth elevation = item.elevation dz = elevation - depth lat = item.lat / 180. * num.pi z = r_earth + dz * num.sin(lat) res[item.nsl()[:2]] = (x, y, z) return res
def to_cartesian(items, reflatlon): res = defaultdict() for i, item in enumerate(items): y, x = ortho.latlon_to_ne(reflatlon, item) depth = item.depth elevation = item.elevation dz = elevation - depth lat = item.lat/180.*num.pi z = r_earth+dz*num.sin(lat) res[item] = (x, y, z) return res
def testLocationObjects(self): class Dummy(object): def __init__(self, lat, lon, depth): self.lat = lat self.lon = lon self.depth = depth a0 = Location(lat=10., lon=12., depth=1100.) a1 = guts.clone(a0) a1.set_origin(lat=9., lon=11) b0 = Location(lat=11., lon=13., depth=2100.) b1 = guts.clone(b0) b1.set_origin(lat=9., lon=11) b2 = Dummy(b0.lat, b0.lon, b0.depth) dist_ab = orthodrome.distance_accurate50m(a0.lat, a0.lon, b0.lat, b0.lon) azi_ab, bazi_ab = orthodrome.azibazi(a0.lat, a0.lon, b0.lat, b0.lon) def g_to_e(*args): return num.array(orthodrome.geodetic_to_ecef(*args)) a_vec = g_to_e(a0.lat, a0.lon, -a0.depth) b_vec = g_to_e(b0.lat, b0.lon, -b0.depth) dist_3d_compare = math.sqrt(num.sum((a_vec - b_vec)**2)) north_shift_compare, east_shift_compare = orthodrome.latlon_to_ne( a0.lat, a0.lon, b0.lat, b0.lon) for a in [a0, a1]: for b in [b0, b1, b2]: dist = a.distance_to(b) assert_allclose(dist, dist_ab) dist_3d = a.distance_3d_to(b) assert_allclose(dist_3d, dist_3d_compare, rtol=0.001) azi, bazi = a.azibazi_to(b) assert_allclose(azi % 360., azi_ab % 360., rtol=1e-2) assert_allclose(bazi % 360., bazi_ab % 360., rtol=1e-2) north_shift, east_shift = a.offset_to(b) assert_allclose((north_shift, east_shift), (north_shift_compare, east_shift_compare), rtol=5e-3) for x, y in [(a0, a1), (b0, b1), (b0, b2), (b1, b2)]: dist = x.distance_to(y) assert_allclose(dist, 0.0)
def to_cartesian(items, latref=None, lonref=None): res = [] latref = latref or 0. lonref = lonref or 0. latlon00 = ortho.Loc(latref, lonref) for i, item in enumerate(items): y, x = ortho.latlon_to_ne(latlon00, item) depth = item.depth * 1000 lat = item.lat / 180. * num.pi res.append((x, y, -depth)) # vielleicht doch als array?! #res = num.array(res) #res = res.T return res
def to_cartesian(items, latref=None, lonref=None): res = [] latref = latref or 0. lonref = lonref or 0. latlon00 = ortho.Loc(latref, lonref) for i, item in enumerate(items): y, x = ortho.latlon_to_ne(latlon00, item) depth = item.depth *1000 lat = item.lat/180.*num.pi res.append((x, y, -depth)) # vielleicht doch als array?! #res = num.array(res) #res = res.T return res
def call(self): self.cleanup() viewer = self.get_viewer() master = viewer.get_active_event() if master is None: self.fail('no master event selected') stations = list(viewer.stations.values()) stations.sort(key=lambda s: (s.network,s.station)) if not stations: self.fail('no station information available') # gather events to be processed events = [] for m in viewer.markers: if isinstance(m, EventMarker): if m.kind == 0: events.append( m.get_event() ) events.sort(key=lambda ev: ev.time) event_to_number = {} for iev, ev in enumerate(events): event_to_number[ev] = iev if self.model_select.startswith('Global'): model_key = 'global' else: model_key = master.lat, master.lon if model_key != self.model_key: if self.model_select.startswith('Global'): self.model = cake.load_model() else: latlon = master.lat, master.lon profile = crust2x2.get_profile(*latlon) profile.set_layer_thickness(crust2x2.LWATER, 0.0) self.model = cake.LayeredModel.from_scanlines( cake.from_crust2x2_profile(profile)) self.model_key = model_key phases = { 'P': ([ cake.PhaseDef(x) for x in 'P p'.split() ], 'Z'), 'S': ([ cake.PhaseDef(x) for x in 'S s'.split() ], 'NE'), } phasenames = phases.keys() phasenames.sort() # synthetic arrivals and ray geometry for master event master_depth = master.depth if self.master_depth_km is not None: master_depth = self.master_depth_km * km tt = {} g = {} for iphase, phasename in enumerate(phasenames): for istation, station in enumerate(stations): dist = orthodrome.distance_accurate50m(master, station) azi = orthodrome.azimuth(master, station) arrivals = self.model.arrivals( phases=phases[phasename][0], distances=[ dist*cake.m2d ], zstart = master_depth, zstop = 0.0) if arrivals: first = arrivals[0] tt[station.network, station.station, phasename] = first.t takeoff = first.takeoff_angle() u = first.path.first_straight().u_in(first.endgaps) g[iphase, istation] = num.array([ math.cos(azi*d2r) * math.sin(takeoff*d2r) * u, math.sin(azi*d2r) * math.sin(takeoff*d2r) * u, math.cos(takeoff*d2r) * u ]) # gather picks for each event for ev in events: picks = {} for m2 in viewer.markers: if isinstance(m2, PhaseMarker) and m2.kind == 0: if m2.get_event() == ev: net, sta, _, _ = m2.one_nslc() picks[net,sta,m2.get_phasename()] = (m2.tmax + m2.tmin) / 2.0 ev.picks = picks # time corrections for extraction windows dataobs = [] datasyn = [] for phasename in phasenames: for station in stations: nsp = station.network, station.station, phasename datasyn.append(tt.get(nsp,None)) for ev in events: if nsp in ev.picks: ttobs = ev.picks[nsp] - ev.time else: ttobs = None dataobs.append(ttobs) ttsyn = num.array(datasyn, dtype=num.float).reshape(( len(phasenames), len(stations))) ttobs = num.array(dataobs, dtype=num.float).reshape(( len(phasenames), len(stations), len(events))) ttres = ttobs - ttsyn[:,:,num.newaxis] tt_corr_event = num.nansum( ttres, axis=1) / \ num.nansum( num.isfinite(ttres), axis=1 ) tt_corr_event = num.where(num.isfinite(tt_corr_event), tt_corr_event, 0.) ttres -= tt_corr_event[:,num.newaxis,:] tt_corr_station = num.nansum( ttres, axis=2) / \ num.nansum( num.isfinite(ttres), axis=2 ) tt_corr_station = num.where(num.isfinite(tt_corr_station), tt_corr_station, 0.) ttres -= tt_corr_station[:,:, num.newaxis] tevents_raw = num.array( [ ev.time for ev in events ] ) tevents_corr = tevents_raw + num.mean(tt_corr_event, axis=0) # print timing information print 'timing stats' for iphasename, phasename in enumerate(phasenames): data = [] for ev in events: iev = event_to_number[ev] for istation, station in enumerate(stations): nsp = station.network, station.station, phasename if nsp in tt and nsp in ev.picks: tarr = ev.time + tt[nsp] tarr_ec = tarr + tt_corr_event[iphasename, iev] tarr_ec_sc = tarr_ec + tt_corr_station[iphasename, istation] tobs = ev.picks[nsp] data.append((tobs-tarr, tobs-tarr_ec, tobs-tarr_ec_sc)) if data: data = num.array(data, dtype=num.float).T print 'event %10s %3s %3i %15.2g %15.2g %15.2g' % ( (ev.name, phasename, data.shape[1]) + tuple( num.mean(num.abs(x)) for x in data )) else: print 'event %10s %3s no picks' % (ev.name, phasename) # extract and preprocess waveforms tpad = 0.0 for f in self.corner_highpass, self.corner_lowpass: if f is not None: tpad = max(tpad, 1.0/f) pile = self.get_pile() waveforms = {} for ev in events: iev = event_to_number[ev] markers = [] for iphasename, phasename in enumerate(phasenames): for istation, station in enumerate(stations): nsp = station.network, station.station, phasename if nsp in tt: tarr = ev.time + tt[nsp] nslcs = [ ( station.network, station.station, '*', '*' ) ] marker = PhaseMarker( nslcs, tarr, tarr, 1, event=ev, phasename=phasename) markers.append(marker) tarr2 = tarr + tt_corr_station[iphasename, istation] + \ tt_corr_event[iphasename, iev] marker = PhaseMarker( nslcs, tarr2, tarr2, 2, event=ev, phasename=phasename) markers.append(marker) tmin = tarr2+self.tstart tmax = tarr2+self.tend marker = PhaseMarker( nslcs, tmin, tmax, 3, event=ev, phasename=phasename) markers.append(marker) trs = pile.all(tmin, tmax, tpad=tpad, trace_selector= lambda tr: tr.nslc_id[:2] == nsp[:2], want_incomplete=False) trok = [] for tr in trs: if num.all(tr.ydata[0] == tr.ydata): continue if self.corner_highpass: tr.highpass(4, self.corner_highpass) if self.corner_lowpass: tr.lowpass(4, self.corner_lowpass) tr.chop(tmin, tmax) tr.set_location(ev.name) #tr.shift( - (tmin - master.time) ) if num.all(num.isfinite(tr.ydata)): trok.append(tr) waveforms[nsp+(iev,)] = trok self.add_markers(markers) def get_channel(trs, cha): for tr in trs: if tr.channel == cha: return tr return None nevents = len(events) nstations = len(stations) nphases = len(phasenames) # correlate waveforms coefs = num.zeros((nphases, nstations, nevents, nevents)) coefs.fill(num.nan) tshifts = coefs.copy() tshifts_picked = coefs.copy() for iphase, phasename in enumerate(phasenames): for istation, station in enumerate(stations): nsp = station.network, station.station, phasename for a in events: ia = event_to_number[a] for b in events: ib = event_to_number[b] if ia == ib: continue if nsp in a.picks and nsp in b.picks: tshifts_picked[iphase,istation,ia,ib] = \ b.picks[nsp] - a.picks[nsp] wa = waveforms[nsp+(ia,)] wb = waveforms[nsp+(ib,)] channels = list(set([ tr.channel for tr in wa + wb ])) channels.sort() tccs = [] for cha in channels: if cha[-1] not in phases[phasename][1]: continue ta = get_channel(wa, cha) tb = get_channel(wb, cha) if ta is None or tb is None: continue tcc = trace.correlate(ta,tb, mode='full', normalization='normal', use_fft=True) tccs.append(tcc) if not tccs: continue tc = None for tcc in tccs: if tc is None: tc = tcc else: tc.add(tcc) tc.ydata *= 1./len(tccs) tmid = tc.tmin*0.5 + tc.tmax*0.5 tlen = (tc.tmax - tc.tmin)*0.5 tc_cut = tc.chop(tmid-tlen*0.5, tmid+tlen*0.5, inplace=False) tshift, coef = tc_cut.max() if (tshift < tc.tmin + 0.5*tc.deltat or tc.tmax - 0.5*tc.deltat < tshift): continue coefs[iphase,istation,ia,ib] = coef tshifts[iphase,istation,ia,ib] = tshift if self.show_correlation_traces: tc.shift(master.time - (tc.tmax + tc.tmin)/2.) self.add_trace(tc) #tshifts = tshifts_picked coefssum_sta = num.nansum(coefs, axis=2) / num.sum(num.isfinite(coefs), axis=2) csum_sta = num.nansum(coefssum_sta, axis=2) / num.sum(num.isfinite(coefssum_sta), axis=2) for iphase, phasename in enumerate(phasenames): for istation, station in enumerate(stations): print 'station %-5s %s %15.2g' % (station.station, phasename, csum_sta[iphase,istation]) coefssum = num.nansum(coefs, axis=1) / num.sum(num.isfinite(coefs), axis=1) csumevent = num.nansum(coefssum, axis=2) / num.sum(num.isfinite(coefssum), axis=2) above = num.where(num.isfinite(coefs), coefs >= self.min_corr, 0) csumabove = num.sum(num.sum(above, axis=1), axis=2) coefssum = num.ma.masked_invalid(coefssum) print 'correlation stats' for iphase, phasename in enumerate(phasenames): for ievent, event in enumerate(events): print 'event %10s %3s %8i %15.2g' % ( event.name, phasename, csumabove[iphase,ievent], csumevent[iphase,ievent]) # plot event correlation matrix fframe = self.figure_frame() fig = fframe.gcf() for iphase, phasename in enumerate(phasenames): p = fig.add_subplot(1,nphases,iphase+1) p.set_xlabel('Event number') p.set_ylabel('Event number') mesh = p.pcolormesh(coefssum[iphase]) cb = fig.colorbar(mesh, ax=p) cb.set_label('Max correlation coefficient') if self.save: fig.savefig(self.output_filename(dir='correlation.pdf')) fig.canvas.draw() # setup and solve linear system data = [] rows = [] weights = [] for iphase in xrange(nphases): for istation in xrange(nstations): for ia in xrange(nevents): for ib in xrange(ia+1,nevents): k = iphase, istation, ia, ib w = coefs[k] if not num.isfinite(tshifts[k]) \ or not num.isfinite(w) or w < self.min_corr: continue row = num.zeros(nevents*4) row[ia*4:ia*4+3] = g[iphase,istation] row[ia*4+3] = -1.0 row[ib*4:ib*4+3] = -g[iphase,istation] row[ib*4+3] = 1.0 weights.append(w) rows.append(row) data.append(tshifts[iphase,istation,ia,ib]) nsamp = len(data) for i in range(4): row = num.zeros(nevents*4) row[i::4] = 1. rows.append(row) data.append(0.0) if self.fix_depth: for ievent in range(nevents): row = num.zeros(nevents*4) row[ievent*4+2] = 1.0 rows.append(row) data.append(0.0) a = num.array(rows, dtype=num.float) d = num.array(data, dtype=num.float) w = num.array(weights, dtype=num.float) if self.weighting == 'equal': w[:nsamp] = 1.0 elif self.weighting == 'linear': pass elif self.weighting == 'quadratic': w[:nsamp] = w[:nsamp]**2 a[:nsamp,:] *= w[:,num.newaxis] d[:nsamp] *= w[:nsamp] x, residuals, rank, singular = num.linalg.lstsq(a,d) x0 = num.zeros(nevents*4) x0[3::4] = tevents_corr mean_abs_residual0 = num.mean( num.abs((num.dot(a[:nsamp], x0) - d[:nsamp])/w[:nsamp])) mean_abs_residual = num.mean( num.abs((num.dot(a[:nsamp],x) - d[:nsamp])/w[:nsamp])) print mean_abs_residual0, mean_abs_residual # distorted solutions npermutations = 100 noiseamount = mean_abs_residual xdistorteds = [] for i in range(npermutations): dnoisy = d.copy() dnoisy[:nsamp] += num.random.normal(size=nsamp)*noiseamount*w[:nsamp] xdistorted, residuals, rank, singular = num.linalg.lstsq(a,dnoisy) xdistorteds.append(xdistorted) mean_abs_residual = num.mean(num.abs(num.dot(a,xdistorted)[:nsamp] - dnoisy[:nsamp])) tmean = num.mean([ e.time for e in events ]) north = x[0::4] east = x[1::4] down = x[2::4] etime = x[3::4] + tmean def plot_range(x): mi, ma = num.percentile(x, [10., 90.]) ext = (ma-mi)/5. mi -= ext ma += ext return mi, ma lat, lon = orthodrome.ne_to_latlon(master.lat, master.lon, north, east) events_out = [] for ievent, event in enumerate(events): event_out = model.Event(time=etime[ievent], lat=lat[ievent], lon=lon[ievent], depth=down[ievent] + master_depth, name = event.name) mark = EventMarker(event_out, kind=4) self.add_marker(mark) events_out.append(event_out) model.Event.dump_catalog(events_out, 'events.relocated.txt') # plot results ned_orig = [] for event in events: n, e = orthodrome.latlon_to_ne(master, event) d = event.depth ned_orig.append((n,e,d)) ned_orig = num.array(ned_orig) ned_orig[:,0] -= num.mean(ned_orig[:,0]) ned_orig[:,1] -= num.mean(ned_orig[:,1]) ned_orig[:,2] -= num.mean(ned_orig[:,2]) north0, east0, down0 = ned_orig.T north2, east2, down2, time2 = num.hstack(xdistorteds).reshape((-1,4)).T fframe = self.figure_frame() fig = fframe.gcf() color_sym = (0.1,0.1,0.0) color_scat = (0.3,0.5,1.0,0.2) d = u'\u0394 ' if not self.fix_depth: p = fig.add_subplot(2,2,1, aspect=1.0) else: p = fig.add_subplot(1,1,1, aspect=1.0) mi_north, ma_north = plot_range(north) mi_east, ma_east = plot_range(east) mi_down, ma_down = plot_range(down) p.set_xlabel(d+'East [km]') p.set_ylabel(d+'North [km]') p.plot(east2/km, north2/km, '.', color=color_scat, markersize=2) p.plot(east/km, north/km, '+', color=color_sym) p.plot(east0/km, north0/km, 'x', color=color_sym) p0 = p for i,ev in enumerate(events): p.text(east[i]/km, north[i]/km, ev.name, clip_on=True) if not self.fix_depth: p = fig.add_subplot(2,2,2, sharey=p0, aspect=1.0) p.set_xlabel(d+'Depth [km]') p.set_ylabel(d+'North [km]') p.plot(down2/km, north2/km, '.', color=color_scat, markersize=2) p.plot(down/km, north/km, '+', color=color_sym) for i,ev in enumerate(events): p.text(down[i]/km, north[i]/km, ev.name, clip_on=True) p1 = p p = fig.add_subplot(2,2,3, sharex=p0, aspect=1.0) p.set_xlabel(d+'East [km]') p.set_ylabel(d+'Depth [km]') p.plot(east2/km, down2/km, '.', color=color_scat, markersize=2) p.plot(east/km, down/km, '+', color=color_sym) for i,ev in enumerate(events): p.text(east[i]/km, down[i]/km, ev.name, clip_on=True) p.invert_yaxis() p2 = p p0.set_xlim(mi_east/km, ma_east/km) p0.set_ylim(mi_north/km, ma_north/km) if not self.fix_depth: p1.set_xlim(mi_down/km, ma_down/km) p2.set_ylim(mi_down/km, ma_down/km) if self.save: fig.savefig(self.output_filename(dir='locations.pdf')) fig.canvas.draw()
def call(self): self.cleanup() viewer = self.get_viewer() master = viewer.get_active_event() if master is None: self.fail('no master event selected') stations = list(viewer.stations.values()) stations.sort(key=lambda s: (s.network, s.station)) if not stations: self.fail('no station information available') # gather events to be processed events = [] for m in viewer.markers: if isinstance(m, EventMarker): if m.kind == 0: events.append(m.get_event()) events.sort(key=lambda ev: ev.time) event_to_number = {} for iev, ev in enumerate(events): event_to_number[ev] = iev if self.model_select.startswith('Global'): model_key = 'global' else: model_key = master.lat, master.lon if model_key != self.model_key: if self.model_select.startswith('Global'): self.model = cake.load_model() else: latlon = master.lat, master.lon profile = crust2x2.get_profile(*latlon) profile.set_layer_thickness(crust2x2.LWATER, 0.0) self.model = cake.LayeredModel.from_scanlines( cake.from_crust2x2_profile(profile)) self.model_key = model_key phases = { 'P': ([cake.PhaseDef(x) for x in 'P p'.split()], 'Z'), 'S': ([cake.PhaseDef(x) for x in 'S s'.split()], 'NE'), } phasenames = list(phases.keys()) phasenames.sort() # synthetic arrivals and ray geometry for master event master_depth = master.depth if self.master_depth_km is not None: master_depth = self.master_depth_km * km tt = {} g = {} for iphase, phasename in enumerate(phasenames): for istation, station in enumerate(stations): dist = orthodrome.distance_accurate50m(master, station) azi = orthodrome.azimuth(master, station) arrivals = self.model.arrivals(phases=phases[phasename][0], distances=[dist * cake.m2d], zstart=master_depth, zstop=0.0) if arrivals: first = arrivals[0] tt[station.network, station.station, phasename] = first.t takeoff = first.takeoff_angle() u = first.path.first_straight().u_in(first.endgaps) g[iphase, istation] = num.array([ math.cos(azi * d2r) * math.sin(takeoff * d2r) * u, math.sin(azi * d2r) * math.sin(takeoff * d2r) * u, math.cos(takeoff * d2r) * u ]) # gather picks for each event for ev in events: picks = {} for m2 in viewer.markers: if isinstance(m2, PhaseMarker) and m2.kind == 0: if m2.get_event() == ev: net, sta, _, _ = m2.one_nslc() picks[net, sta, m2.get_phasename()] = (m2.tmax + m2.tmin) / 2.0 ev.picks = picks # time corrections for extraction windows dataobs = [] datasyn = [] for phasename in phasenames: for station in stations: nsp = station.network, station.station, phasename datasyn.append(tt.get(nsp, None)) for ev in events: if nsp in ev.picks: ttobs = ev.picks[nsp] - ev.time else: ttobs = None dataobs.append(ttobs) ttsyn = num.array(datasyn, dtype=num.float).reshape( (len(phasenames), len(stations))) ttobs = num.array(dataobs, dtype=num.float).reshape( (len(phasenames), len(stations), len(events))) ttres = ttobs - ttsyn[:, :, num.newaxis] tt_corr_event = num.nansum( ttres, axis=1) / \ num.nansum( num.isfinite(ttres), axis=1 ) tt_corr_event = num.where(num.isfinite(tt_corr_event), tt_corr_event, 0.) ttres -= tt_corr_event[:, num.newaxis, :] tt_corr_station = num.nansum( ttres, axis=2) / \ num.nansum( num.isfinite(ttres), axis=2 ) tt_corr_station = num.where(num.isfinite(tt_corr_station), tt_corr_station, 0.) ttres -= tt_corr_station[:, :, num.newaxis] tevents_raw = num.array([ev.time for ev in events]) tevents_corr = tevents_raw + num.mean(tt_corr_event, axis=0) # print timing information print('timing stats') for iphasename, phasename in enumerate(phasenames): data = [] for ev in events: iev = event_to_number[ev] for istation, station in enumerate(stations): nsp = station.network, station.station, phasename if nsp in tt and nsp in ev.picks: tarr = ev.time + tt[nsp] tarr_ec = tarr + tt_corr_event[iphasename, iev] tarr_ec_sc = tarr_ec + tt_corr_station[iphasename, istation] tobs = ev.picks[nsp] data.append( (tobs - tarr, tobs - tarr_ec, tobs - tarr_ec_sc)) if data: data = num.array(data, dtype=num.float).T print('event %10s %3s %3i %15.2g %15.2g %15.2g' % ((ev.name, phasename, data.shape[1]) + tuple(num.mean(num.abs(x)) for x in data))) else: print('event %10s %3s no picks' % (ev.name, phasename)) # extract and preprocess waveforms tpad = 0.0 for f in self.corner_highpass, self.corner_lowpass: if f is not None: tpad = max(tpad, 1.0 / f) pile = self.get_pile() waveforms = {} for ev in events: iev = event_to_number[ev] markers = [] for iphasename, phasename in enumerate(phasenames): for istation, station in enumerate(stations): nsp = station.network, station.station, phasename if nsp in tt: tarr = ev.time + tt[nsp] nslcs = [(station.network, station.station, '*', '*')] marker = PhaseMarker(nslcs, tarr, tarr, 1, event=ev, phasename=phasename) markers.append(marker) tarr2 = tarr + tt_corr_station[iphasename, istation] + \ tt_corr_event[iphasename, iev] marker = PhaseMarker(nslcs, tarr2, tarr2, 2, event=ev, phasename=phasename) markers.append(marker) tmin = tarr2 + self.tstart tmax = tarr2 + self.tend marker = PhaseMarker(nslcs, tmin, tmax, 3, event=ev, phasename=phasename) markers.append(marker) trs = pile.all(tmin, tmax, tpad=tpad, trace_selector=lambda tr: tr.nslc_id[:2] == nsp[:2], want_incomplete=False) trok = [] for tr in trs: if num.all(tr.ydata[0] == tr.ydata): continue if self.corner_highpass: tr.highpass(4, self.corner_highpass) if self.corner_lowpass: tr.lowpass(4, self.corner_lowpass) tr.chop(tmin, tmax) tr.set_location(ev.name) #tr.shift( - (tmin - master.time) ) if num.all(num.isfinite(tr.ydata)): trok.append(tr) waveforms[nsp + (iev, )] = trok self.add_markers(markers) def get_channel(trs, cha): for tr in trs: if tr.channel == cha: return tr return None nevents = len(events) nstations = len(stations) nphases = len(phasenames) # correlate waveforms coefs = num.zeros((nphases, nstations, nevents, nevents)) coefs.fill(num.nan) tshifts = coefs.copy() tshifts_picked = coefs.copy() for iphase, phasename in enumerate(phasenames): for istation, station in enumerate(stations): nsp = station.network, station.station, phasename for a in events: ia = event_to_number[a] for b in events: ib = event_to_number[b] if ia == ib: continue if nsp in a.picks and nsp in b.picks: tshifts_picked[iphase,istation,ia,ib] = \ b.picks[nsp] - a.picks[nsp] wa = waveforms[nsp + (ia, )] wb = waveforms[nsp + (ib, )] channels = list(set([tr.channel for tr in wa + wb])) channels.sort() tccs = [] for cha in channels: if cha[-1] not in phases[phasename][1]: continue ta = get_channel(wa, cha) tb = get_channel(wb, cha) if ta is None or tb is None: continue tcc = trace.correlate(ta, tb, mode='full', normalization='normal', use_fft=True) tccs.append(tcc) if not tccs: continue tc = None for tcc in tccs: if tc is None: tc = tcc else: tc.add(tcc) tc.ydata *= 1. / len(tccs) tmid = tc.tmin * 0.5 + tc.tmax * 0.5 tlen = (tc.tmax - tc.tmin) * 0.5 tc_cut = tc.chop(tmid - tlen * 0.5, tmid + tlen * 0.5, inplace=False) tshift, coef = tc_cut.max() if (tshift < tc.tmin + 0.5 * tc.deltat or tc.tmax - 0.5 * tc.deltat < tshift): continue coefs[iphase, istation, ia, ib] = coef tshifts[iphase, istation, ia, ib] = tshift if self.show_correlation_traces: tc.shift(master.time - (tc.tmax + tc.tmin) / 2.) self.add_trace(tc) #tshifts = tshifts_picked coefssum_sta = num.nansum(coefs, axis=2) / num.sum(num.isfinite(coefs), axis=2) csum_sta = num.nansum(coefssum_sta, axis=2) / num.sum( num.isfinite(coefssum_sta), axis=2) for iphase, phasename in enumerate(phasenames): for istation, station in enumerate(stations): print('station %-5s %s %15.2g' % (station.station, phasename, csum_sta[iphase, istation])) coefssum = num.nansum(coefs, axis=1) / num.sum(num.isfinite(coefs), axis=1) csumevent = num.nansum(coefssum, axis=2) / num.sum( num.isfinite(coefssum), axis=2) above = num.where(num.isfinite(coefs), coefs >= self.min_corr, 0) csumabove = num.sum(num.sum(above, axis=1), axis=2) coefssum = num.ma.masked_invalid(coefssum) print('correlation stats') for iphase, phasename in enumerate(phasenames): for ievent, event in enumerate(events): print('event %10s %3s %8i %15.2g' % (event.name, phasename, csumabove[iphase, ievent], csumevent[iphase, ievent])) # plot event correlation matrix fframe = self.figure_frame() fig = fframe.gcf() for iphase, phasename in enumerate(phasenames): p = fig.add_subplot(1, nphases, iphase + 1) p.set_xlabel('Event number') p.set_ylabel('Event number') mesh = p.pcolormesh(coefssum[iphase]) cb = fig.colorbar(mesh, ax=p) cb.set_label('Max correlation coefficient') if self.save: fig.savefig(self.output_filename(dir='correlation.pdf')) fig.canvas.draw() # setup and solve linear system data = [] rows = [] weights = [] for iphase in range(nphases): for istation in range(nstations): for ia in range(nevents): for ib in range(ia + 1, nevents): k = iphase, istation, ia, ib w = coefs[k] if not num.isfinite(tshifts[k]) \ or not num.isfinite(w) or w < self.min_corr: continue row = num.zeros(nevents * 4) row[ia * 4:ia * 4 + 3] = g[iphase, istation] row[ia * 4 + 3] = -1.0 row[ib * 4:ib * 4 + 3] = -g[iphase, istation] row[ib * 4 + 3] = 1.0 weights.append(w) rows.append(row) data.append(tshifts[iphase, istation, ia, ib]) nsamp = len(data) for i in range(4): row = num.zeros(nevents * 4) row[i::4] = 1. rows.append(row) data.append(0.0) if self.fix_depth: for ievent in range(nevents): row = num.zeros(nevents * 4) row[ievent * 4 + 2] = 1.0 rows.append(row) data.append(0.0) a = num.array(rows, dtype=num.float) d = num.array(data, dtype=num.float) w = num.array(weights, dtype=num.float) if self.weighting == 'equal': w[:nsamp] = 1.0 elif self.weighting == 'linear': pass elif self.weighting == 'quadratic': w[:nsamp] = w[:nsamp]**2 a[:nsamp, :] *= w[:, num.newaxis] d[:nsamp] *= w[:nsamp] x, residuals, rank, singular = num.linalg.lstsq(a, d) x0 = num.zeros(nevents * 4) x0[3::4] = tevents_corr mean_abs_residual0 = num.mean( num.abs((num.dot(a[:nsamp], x0) - d[:nsamp]) / w[:nsamp])) mean_abs_residual = num.mean( num.abs((num.dot(a[:nsamp], x) - d[:nsamp]) / w[:nsamp])) print(mean_abs_residual0, mean_abs_residual) # distorted solutions npermutations = 100 noiseamount = mean_abs_residual xdistorteds = [] for i in range(npermutations): dnoisy = d.copy() dnoisy[:nsamp] += num.random.normal( size=nsamp) * noiseamount * w[:nsamp] xdistorted, residuals, rank, singular = num.linalg.lstsq(a, dnoisy) xdistorteds.append(xdistorted) mean_abs_residual = num.mean( num.abs(num.dot(a, xdistorted)[:nsamp] - dnoisy[:nsamp])) tmean = num.mean([e.time for e in events]) north = x[0::4] east = x[1::4] down = x[2::4] etime = x[3::4] + tmean def plot_range(x): mi, ma = num.percentile(x, [10., 90.]) ext = (ma - mi) / 5. mi -= ext ma += ext return mi, ma lat, lon = orthodrome.ne_to_latlon(master.lat, master.lon, north, east) events_out = [] for ievent, event in enumerate(events): event_out = model.Event(time=etime[ievent], lat=lat[ievent], lon=lon[ievent], depth=down[ievent] + master_depth, name=event.name) mark = EventMarker(event_out, kind=4) self.add_marker(mark) events_out.append(event_out) model.Event.dump_catalog(events_out, 'events.relocated.txt') # plot results ned_orig = [] for event in events: n, e = orthodrome.latlon_to_ne(master, event) d = event.depth ned_orig.append((n, e, d)) ned_orig = num.array(ned_orig) ned_orig[:, 0] -= num.mean(ned_orig[:, 0]) ned_orig[:, 1] -= num.mean(ned_orig[:, 1]) ned_orig[:, 2] -= num.mean(ned_orig[:, 2]) north0, east0, down0 = ned_orig.T north2, east2, down2, time2 = num.hstack(xdistorteds).reshape( (-1, 4)).T fframe = self.figure_frame() fig = fframe.gcf() color_sym = (0.1, 0.1, 0.0) color_scat = (0.3, 0.5, 1.0, 0.2) d = u'\u0394 ' if not self.fix_depth: p = fig.add_subplot(2, 2, 1, aspect=1.0) else: p = fig.add_subplot(1, 1, 1, aspect=1.0) mi_north, ma_north = plot_range(north) mi_east, ma_east = plot_range(east) mi_down, ma_down = plot_range(down) p.set_xlabel(d + 'East [km]') p.set_ylabel(d + 'North [km]') p.plot(east2 / km, north2 / km, '.', color=color_scat, markersize=2) p.plot(east / km, north / km, '+', color=color_sym) p.plot(east0 / km, north0 / km, 'x', color=color_sym) p0 = p for i, ev in enumerate(events): p.text(east[i] / km, north[i] / km, ev.name, clip_on=True) if not self.fix_depth: p = fig.add_subplot(2, 2, 2, sharey=p0, aspect=1.0) p.set_xlabel(d + 'Depth [km]') p.set_ylabel(d + 'North [km]') p.plot(down2 / km, north2 / km, '.', color=color_scat, markersize=2) p.plot(down / km, north / km, '+', color=color_sym) for i, ev in enumerate(events): p.text(down[i] / km, north[i] / km, ev.name, clip_on=True) p1 = p p = fig.add_subplot(2, 2, 3, sharex=p0, aspect=1.0) p.set_xlabel(d + 'East [km]') p.set_ylabel(d + 'Depth [km]') p.plot(east2 / km, down2 / km, '.', color=color_scat, markersize=2) p.plot(east / km, down / km, '+', color=color_sym) for i, ev in enumerate(events): p.text(east[i] / km, down[i] / km, ev.name, clip_on=True) p.invert_yaxis() p2 = p p0.set_xlim(mi_east / km, ma_east / km) p0.set_ylim(mi_north / km, ma_north / km) if not self.fix_depth: p1.set_xlim(mi_down / km, ma_down / km) p2.set_ylim(mi_down / km, ma_down / km) if self.save: fig.savefig(self.output_filename(dir='locations.pdf')) fig.canvas.draw()
from pyrocko import orthodrome # option 1, coordinates as floats north_m, east_m = orthodrome.latlon_to_ne( 10.3, # origin latitude 12.4, # origin longitude 10.5, # target latitude 12.6) # target longitude print(north_m, east_m) # >>> 22199.7843582 21821.3511789 # option 2, coordinates from instances with 'lon' and 'lat' attributes from pyrocko.gf import seismosizer # noqa source = seismosizer.DCSource(lat=10.3, lon=12.4) target = seismosizer.Target(lat=10.5, lon=12.6) north_m, east_m = orthodrome.latlon_to_ne(source, target) print(north_m, east_m) # >>> 22199.7843582 21821.3511789
for m in markers: if not isinstance(m, PhaseMarker): continue if not m.get_phasename().upper() == wanted_phase: continue event = m.get_event() if not event: continue append_to_dict(by_event, event, m) by_station = {} coordinates = {} for event, markers in by_event.items(): x,y = orthodrome.latlon_to_ne(min_lat, min_lon, event.lat, event.lon) for m in markers: nsl = m.one_nslc()[:3] tt_p = m.tmin - event.time append_to_dict(by_station, nsl, (x,y,event.depth, tt_p)) #print(by_station) # dict containing the not not-picked events for all stations ''' by_event_nott = {} for m in markers: if isinstance(m, PhaseMarker):
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 plot_polarizations(stations, trs, event=None, size_factor=0.05, fontsize=10., output_filename=None, output_format=None, output_dpi=None): if event is None: slats = num.array([s.lat for s in stations], dtype=num.float) slons = num.array([s.lon for s in stations], dtype=num.float) clat, clon = od.geographic_midpoint(slats, slons) event = od.Loc(clat, clon) nsl_c_to_trs = defaultdict(dict) for tr in trs: nsl_c_to_trs[tr.nslc_id[:3]][tr.nslc_id[3]] = tr nsl_to_station = dict((s.nsl(), s) for s in stations) plot.mpl_init(fontsize=fontsize) fig = plt.figure(figsize=plot.mpl_papersize('a4', 'landscape')) plot.mpl_margins(fig, w=7., h=6., units=fontsize) grid = ImageGrid(fig, 111, nrows_ncols=(2, 2), axes_pad=0.5, add_all=True, label_mode='L', aspect=True) axes_en = grid[0] axes_en.set_ylabel('Northing [km]') axes_dn = grid[1] axes_dn.locator_params(axis='x', nbins=4) axes_dn.set_xlabel('Depth [km]') axes_ed = grid[2] axes_ed.locator_params(axis='y', nbins=4) axes_ed.set_ylabel('Depth [km]') axes_ed.set_xlabel('Easting [km]') if isinstance(event, model.Event): axes_en.plot(0., 0., '*') axes_dn.plot(event.depth / km, 0., '*') axes_ed.plot(0., event.depth / km, '*') grid[3].set_axis_off() locations = [] for nsl in sorted(nsl_c_to_trs.keys()): station = nsl_to_station[nsl] n, e = od.latlon_to_ne(event.lat, event.lon, station.lat, station.lon) locations.append((n, e)) ns, es = num.array(locations, dtype=num.float).T n_min = num.min(ns) n_max = num.max(ns) e_min = num.min(es) e_max = num.max(es) factor = max((n_max - n_min) * size_factor, (e_max - e_min) * size_factor) fontsize_annot = fontsize * 0.7 data = {} for insl, nsl in enumerate(sorted(nsl_c_to_trs.keys())): color = plot.mpl_graph_color(insl) try: tr_e = nsl_c_to_trs[nsl]['E'] tr_n = nsl_c_to_trs[nsl]['N'] tr_z = nsl_c_to_trs[nsl]['Z'] except KeyError: continue station = nsl_to_station[nsl] n, e = od.latlon_to_ne(event.lat, event.lon, station.lat, station.lon) d = station.depth axes_en.annotate('.'.join(x for x in nsl if x), xy=(e / km, n / km), xycoords='data', xytext=(fontsize_annot / 3., fontsize_annot / 3.), textcoords='offset points', verticalalignment='bottom', horizontalalignment='left', rotation=0., size=fontsize_annot) axes_en.plot(e / km, n / km, '^', mfc=color, mec=darken(color)) axes_dn.plot(d / km, n / km, '^', mfc=color, mec=darken(color)) axes_ed.plot(e / km, d / km, '^', mfc=color, mec=darken(color)) arr_e = tr_e.ydata arr_n = tr_n.ydata arr_z = tr_z.ydata arr_t = tr_z.get_xdata() data[nsl] = (arr_e, arr_n, arr_z, arr_t, n, e, d, color) amaxs = [] amax_hors = [] for nsl in sorted(data.keys()): arr_e, arr_n, arr_z, arr_t, n, e, d, color = data[nsl] amaxs.append(num.max(num.abs(num.sqrt(arr_e**2 + arr_n**2 + arr_z**2)))) amax_hors.append(num.max(num.abs(num.sqrt(arr_e**2 + arr_n**2)))) amax = num.median(amaxs) amax_hor = num.median(amax_hors) for nsl in sorted(data.keys()): arr_e, arr_n, arr_z, arr_t, n, e, d, color = data[nsl] tmin = arr_t.min() tmax = arr_t.max() plot_color_line(axes_en, (e + arr_e / amax_hor * factor) / km, (n + arr_n / amax_hor * factor) / km, arr_t, color, tmin, tmax) plot_color_line(axes_dn, (d - arr_z / amax * factor) / km, (n + arr_n / amax * factor) / km, arr_t, color, tmin, tmax) plot_color_line(axes_ed, (e + arr_e / amax * factor) / km, (d - arr_z / amax * factor) / km, arr_t, color, tmin, tmax) axes_ed.invert_yaxis() for axes in (axes_dn, axes_ed, axes_en): axes.autoscale_view(tight=True) if output_filename is None: plt.show() else: fig.savefig(output_filename, format=output_format, dpi=output_dpi)