|
|
|
@ -1,8 +1,87 @@
|
|
|
|
|
import numpy as num
|
|
|
|
|
import matplotlib
|
|
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
|
|
|
|
|
|
from pyrocko.gui.snuffling import Snuffling, Param, Switch
|
|
|
|
|
from pyrocko import orthodrome as ortho
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
from vtk.util import numpy_support
|
|
|
|
|
except ImportError as e:
|
|
|
|
|
vtk = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ColorMapper():
|
|
|
|
|
def __init__(self, cmap):
|
|
|
|
|
self.cmap = plt.get_cmap(cmap)
|
|
|
|
|
self.set_range(0., 1.)
|
|
|
|
|
|
|
|
|
|
def set_range(self, min, max):
|
|
|
|
|
self.mapping = matplotlib.cm.ScalarMappable(
|
|
|
|
|
norm=matplotlib.colors.Normalize(min, max),
|
|
|
|
|
cmap=self.cmap)
|
|
|
|
|
|
|
|
|
|
def __call__(self, v):
|
|
|
|
|
return self.mapping.to_rgba(v)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 events_to_vtksphere_actors(events, z_scale, size=500.):
|
|
|
|
|
|
|
|
|
|
ns, es, depths = locations_to_ned(events)
|
|
|
|
|
times = [e.time for e in events]
|
|
|
|
|
|
|
|
|
|
if not times:
|
|
|
|
|
times = num.ones(ntuples)
|
|
|
|
|
|
|
|
|
|
adata = num.array((es, ns, -depths))
|
|
|
|
|
adata = adata.flatten(order='F')
|
|
|
|
|
data = numpy_support.numpy_to_vtk(
|
|
|
|
|
adata, deep=True, array_type=vtk.VTK_FLOAT)
|
|
|
|
|
data.SetNumberOfComponents(3)
|
|
|
|
|
actors = []
|
|
|
|
|
ntuples = data.GetNumberOfTuples()
|
|
|
|
|
|
|
|
|
|
cmap = plt.get_cmap
|
|
|
|
|
|
|
|
|
|
for i in range(ntuples):
|
|
|
|
|
source = vtk.vtkSphereSource()
|
|
|
|
|
source.SetCenter(*data.GetTuple3(i))
|
|
|
|
|
source.SetRadius(size)
|
|
|
|
|
source.Update()
|
|
|
|
|
|
|
|
|
|
mapper = vtk.vtkPolyDataMapper()
|
|
|
|
|
mapper.SetInputConnection(source.GetOutputPort())
|
|
|
|
|
|
|
|
|
|
actor = vtk.vtkActor()
|
|
|
|
|
actor.SetMapper(mapper)
|
|
|
|
|
|
|
|
|
|
r, g, b, a = events[i].get_vtk_color(events[i].time)
|
|
|
|
|
actor.GetProperty().SetColor(r, g, b)
|
|
|
|
|
actors.append(actor)
|
|
|
|
|
|
|
|
|
|
return actors
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VtkTest(Snuffling):
|
|
|
|
|
|
|
|
|
@ -38,29 +117,9 @@ class VtkTest(Snuffling):
|
|
|
|
|
self.add_parameter(Switch('Topography smoothing', 'smoothing', False))
|
|
|
|
|
self.add_trigger('Make screenshot', self.save_image)
|
|
|
|
|
self.actors = []
|
|
|
|
|
self.topo_actor = None
|
|
|
|
|
self.frame = None
|
|
|
|
|
self.set_live_update(False)
|
|
|
|
|
|
|
|
|
|
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 stations_to_vtkcone_actors(self, data, size=500.):
|
|
|
|
|
actors = []
|
|
|
|
@ -80,41 +139,10 @@ class VtkTest(Snuffling):
|
|
|
|
|
|
|
|
|
|
return actors
|
|
|
|
|
|
|
|
|
|
def events_to_vtksphere_actors(self, data, times=None, size=500.):
|
|
|
|
|
actors = []
|
|
|
|
|
ntuples = data.GetNumberOfTuples()
|
|
|
|
|
|
|
|
|
|
if not times:
|
|
|
|
|
times = num.ones(ntuples)
|
|
|
|
|
|
|
|
|
|
tmin = min(times)
|
|
|
|
|
tmax = max(times)
|
|
|
|
|
|
|
|
|
|
for i in xrange(ntuples):
|
|
|
|
|
source = vtk.vtkSphereSource()
|
|
|
|
|
source.SetCenter(*data.GetTuple3(i))
|
|
|
|
|
source.SetRadius(size)
|
|
|
|
|
source.Update()
|
|
|
|
|
|
|
|
|
|
mapper = vtk.vtkPolyDataMapper()
|
|
|
|
|
mapper.SetInputConnection(source.GetOutputPort())
|
|
|
|
|
|
|
|
|
|
actor = vtk.vtkActor()
|
|
|
|
|
actor.SetMapper(mapper)
|
|
|
|
|
tscaled = (times[i]-tmin)/(tmax-tmin)
|
|
|
|
|
r = (1-tscaled)
|
|
|
|
|
g = 0.
|
|
|
|
|
b = tscaled
|
|
|
|
|
actor.GetProperty().SetColor(r, g, b)
|
|
|
|
|
actors.append(actor)
|
|
|
|
|
|
|
|
|
|
return actors
|
|
|
|
|
|
|
|
|
|
def call(self):
|
|
|
|
|
try:
|
|
|
|
|
global vtk
|
|
|
|
|
import vtk
|
|
|
|
|
from vtk.util import numpy_support
|
|
|
|
|
import sys
|
|
|
|
|
sys.path[0:0] = [self.module_dir()]
|
|
|
|
|
from grid_topo import setup_vtk_map_actor
|
|
|
|
@ -124,6 +152,8 @@ class VtkTest(Snuffling):
|
|
|
|
|
vtk = None
|
|
|
|
|
|
|
|
|
|
self.cleanup()
|
|
|
|
|
viewer = self.get_viewer()
|
|
|
|
|
|
|
|
|
|
stations = []
|
|
|
|
|
events = []
|
|
|
|
|
cone_actors = []
|
|
|
|
@ -140,6 +170,26 @@ class VtkTest(Snuffling):
|
|
|
|
|
self.get_event_markers())
|
|
|
|
|
events = [m.get_event() for m in markers]
|
|
|
|
|
|
|
|
|
|
active_event = viewer.get_active_event()
|
|
|
|
|
to_rgba = ColorMapper('summer')
|
|
|
|
|
times = [e.time for e in events]
|
|
|
|
|
to_rgba.set_range(min(times), max(times))
|
|
|
|
|
if active_event:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
to_rgba = ColorMapper('gray')
|
|
|
|
|
to_rgba.set_range(min(times), max(times))
|
|
|
|
|
|
|
|
|
|
for e in events:
|
|
|
|
|
e.get_vtk_color = to_rgba
|
|
|
|
|
|
|
|
|
|
if active_event:
|
|
|
|
|
def return_red(e):
|
|
|
|
|
return (1., 0., 0., 1.)
|
|
|
|
|
|
|
|
|
|
active_event.get_vtk_color = return_red
|
|
|
|
|
events.append(active_event)
|
|
|
|
|
|
|
|
|
|
all_lats = []
|
|
|
|
|
all_lons = []
|
|
|
|
|
|
|
|
|
@ -163,18 +213,12 @@ class VtkTest(Snuffling):
|
|
|
|
|
size = distance_max / 50.
|
|
|
|
|
|
|
|
|
|
if len(events) != 0:
|
|
|
|
|
ns, es, depths = self.locations_to_ned(events)
|
|
|
|
|
times = [e.time for e in events]
|
|
|
|
|
adata = num.array((es, ns, -depths))
|
|
|
|
|
adata = adata.flatten(order='F')
|
|
|
|
|
data = numpy_support.numpy_to_vtk(
|
|
|
|
|
adata, deep=True, array_type=vtk.VTK_FLOAT)
|
|
|
|
|
data.SetNumberOfComponents(3)
|
|
|
|
|
sphere_actors = self.events_to_vtksphere_actors(data, times, size=size/2.)
|
|
|
|
|
sphere_actors = events_to_vtksphere_actors(
|
|
|
|
|
events, z_scale=self.z_scale, size=size/2.)
|
|
|
|
|
|
|
|
|
|
if len(stations) != 0:
|
|
|
|
|
ns, es, depths = self.locations_to_ned(stations,
|
|
|
|
|
has_elevation=True)
|
|
|
|
|
ns, es, depths = locations_to_ned(
|
|
|
|
|
stations, z_scale=self.z_scale, has_elevation=True)
|
|
|
|
|
adata = num.array((es, ns, -depths)).flatten(order='F')
|
|
|
|
|
data = numpy_support.numpy_to_vtk(
|
|
|
|
|
adata, deep=True, array_type=vtk.VTK_FLOAT)
|
|
|
|
@ -183,8 +227,8 @@ class VtkTest(Snuffling):
|
|
|
|
|
cone_actors = self.stations_to_vtkcone_actors(data, size=size)
|
|
|
|
|
|
|
|
|
|
if self.want_topo:
|
|
|
|
|
distance_max += self.margin_radius * 1000
|
|
|
|
|
self.topo_actor = setup_vtk_map_actor(
|
|
|
|
|
distance_max += self.margin_radius * 1000.
|
|
|
|
|
topo_actor = setup_vtk_map_actor(
|
|
|
|
|
center_lat, center_lon, distance_max,
|
|
|
|
|
super_elevation=self.z_scale,
|
|
|
|
|
decimation=int(self.z_decimation or 1),
|
|
|
|
@ -199,8 +243,8 @@ class VtkTest(Snuffling):
|
|
|
|
|
for actor in sphere_actors:
|
|
|
|
|
self.frame.add_actor(actor)
|
|
|
|
|
|
|
|
|
|
if self.topo_actor:
|
|
|
|
|
self.frame.add_actor(self.topo_actor)
|
|
|
|
|
if self.want_topo:
|
|
|
|
|
self.frame.add_actor(topo_actor)
|
|
|
|
|
self.frame.renderer.SetBackground(0.01, 0.05, 0.1)
|
|
|
|
|
|
|
|
|
|
self.frame.init()
|
|
|
|
|