[segyio] 17/376: Moved viewer to applications

Jørgen Kvalsvik jokva-guest at moszumanska.debian.org
Wed Sep 20 08:04:00 UTC 2017


This is an automated email from the git hooks/post-receive script.

jokva-guest pushed a commit to branch debian
in repository segyio.

commit 54d4801af8e7d48bdc95b0bd7c41f124afc4a176
Author: Thorvald Johannessen <thorvjo at statoil.com>
Date:   Thu Oct 6 13:40:05 2016 +0200

    Moved viewer to applications
    
    Included viewer in make install, and enabled running python without
    specifying python bin.
---
 CMakeLists.txt              |   1 +
 applications/CMakeLists.txt |   5 +
 applications/segyviewer.py  | 389 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 395 insertions(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 00856fd..5b93f8e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -54,3 +54,4 @@ endif()
 add_subdirectory(python)
 add_subdirectory(tests)
 add_subdirectory(examples)
+add_subdirectory(applications)
diff --git a/applications/CMakeLists.txt b/applications/CMakeLists.txt
new file mode 100644
index 0000000..08d5803
--- /dev/null
+++ b/applications/CMakeLists.txt
@@ -0,0 +1,5 @@
+configure_file(segyviewer.py segyviewer COPYONLY)
+
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/segyviewer
+        PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_EXECUTE WORLD_READ
+        DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
diff --git a/applications/segyviewer.py b/applications/segyviewer.py
new file mode 100644
index 0000000..fd7bbec
--- /dev/null
+++ b/applications/segyviewer.py
@@ -0,0 +1,389 @@
+#!/usr/bin/env python
+
+import segyio
+
+from pylab import *
+
+from PyQt4 import QtGui, QtCore
+
+from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
+from matplotlib.figure import Figure
+import matplotlib.patches as patches
+
+
+class LineSelectionMonitor(QtCore.QObject):
+    ilineChanged = QtCore.pyqtSignal(int)
+    xlineChanged = QtCore.pyqtSignal(int)
+    depthChanged = QtCore.pyqtSignal(int)
+
+    def __init__(self, parent):
+        QtCore.QObject.__init__(self, parent)
+
+    def ilineUpdated(self, new_index):
+        self.ilineChanged.emit(new_index)
+
+    def xlineUpdated(self, new_index):
+        self.xlineChanged.emit(new_index)
+
+    def depthUpdated(self, new_index):
+        self.depthChanged.emit(new_index)
+
+class ColorMapMonitor(QtCore.QObject):
+    cmap_changed = QtCore.pyqtSignal(str)
+
+    def __init__(self, parent=None):
+        QtCore.QObject.__init__(self, parent)
+
+    def colormapUpdated(self, value):
+        self.cmap_changed.emit(str(value))
+
+
+class PlaneCanvas(FigureCanvas):
+    """
+    Generic plot canvas for all plane views
+    """
+    indexChanged = QtCore.pyqtSignal(int)
+
+    def __init__(self, planes, indexes, axis_indexes, dataset_title, cmap, display_horizontal_indicator=False,
+                 display_vertical_indicator=False, parent=None, width=800, height=100, dpi=20, v_min_max=None):
+
+        self.planes = planes
+        self.indexes = indexes
+        self.x_axis_indexes, self.y_axis_indexes = axis_indexes[0], axis_indexes[1]
+
+        self.dataset_title = dataset_title
+
+        self.fig = Figure(figsize=(width, height), dpi=dpi, facecolor='white')
+        FigureCanvas.__init__(self, self.fig)
+
+        self.setParent(parent)
+
+        self.axes = self.fig.add_subplot(111)
+
+        self.axes.tick_params(labelsize=30)
+
+        # the default colormap
+        self.cmap = cmap
+
+        self.im = self.axes.imshow(planes[indexes[0]].T, interpolation="nearest", aspect="auto", cmap=self.cmap, vmin=v_min_max[0], vmax=v_min_max[1])
+
+        self.current_index = 0
+
+        # connecting matplotlib mouse signals
+        self.mpl_connect('motion_notify_event', self.mouse_moved)
+        self.mpl_connect('button_press_event', self.mouse_clicked)
+        self.mpl_connect('axes_leave_event', self.mouse_left)
+
+        if display_vertical_indicator:
+            self.verdical_indicator_rect = self.axes.add_patch(
+                patches.Rectangle(
+                    (-0.5, 0),  # (x,y)
+                    1,  # width - bredde er pr dot ikke pixel...
+                    len(self.planes[self.indexes[0]][0]),  # height / depth
+                    fill=False,
+                    alpha=1,
+                    color='black',
+                    linestyle='--',
+                    linewidth=2
+                )
+            )
+
+        if display_horizontal_indicator:
+            self.horizontal_indicator_rect = self.axes.add_patch(
+                patches.Rectangle(
+                    (-0.5, 0),
+                    len(self.planes[self.indexes[0]][0]),
+                    1,
+                    fill=False,
+                    alpha=1,
+                    color='black',
+                    linestyle='--',
+                    linewidth=2
+                )
+            )
+
+        self.disabled_overlay = self.axes.add_patch(
+            patches.Rectangle(
+                (-0.5, 0),  # (x,y)
+                len(self.planes[self.indexes[0]][0]),
+                len(self.planes[self.indexes[0]][0]),
+                alpha=0.5,
+                color='gray',
+                visible=False
+            )
+        )
+
+
+    def mouse_left(self, evt):
+        # for now do nothing
+        # self.set_vertical_line_indicator(self.current_index)
+        pass
+
+
+    def mouse_clicked(self, evt):
+        if evt.inaxes:
+            self.current_index = int(evt.xdata)
+            self.indexChanged.emit(self.x_axis_indexes[int(evt.xdata)])
+
+    def mouse_moved(self, evt):
+
+        # if evt.inaxes:
+        #   self.set_vertical_line_indicator(int(evt.xdata))
+        pass
+
+    def set_colormap(self, cmap):
+        self.cmap = cmap
+        self.im.set_cmap(cmap)
+        self.draw()
+
+    def update_image(self, index):
+        self.im.set_data(self.planes[index].T)
+        self.draw()
+
+    def set_vertical_line_indicator(self, line_index):
+        self.verdical_indicator_rect.set_x(self.x_axis_indexes.index(line_index) - 0.5)
+        self.verdical_indicator_rect.set_y(0)
+        self.draw()
+
+    def set_horizontal_line_indicator(self, line_index):
+        self.horizontal_indicator_rect.set_x(-0.5)
+
+        self.horizontal_indicator_rect.set_y(self.y_axis_indexes.index(line_index))
+        self.draw()
+
+    def enable_overlay(self):
+        self.disabled_overlay.set_visible(True)
+        self.draw()
+
+    def disable_overlay(self):
+        self.disabled_overlay.set_visible(False)
+        self.draw()
+
+
+class PlotWidget(QtGui.QWidget):
+    """
+    Main widget holding the figure and slider
+    """
+
+    def __init__(self, planes, indexes, axis_indexes, dataset_title, default_cmap='seismic',
+                 show_h_indicator=False, show_v_indicator=False, v_min_max=None):
+        super(PlotWidget, self).__init__()
+
+        self.planes = planes
+        self.indexes = indexes
+        self.dataset_title = dataset_title
+        self.default_cmap = default_cmap
+        self.show_h_indicator = show_h_indicator
+        self.show_v_indicator = show_v_indicator
+        self.setAutoFillBackground(True)
+        p = self.palette()
+        p.setColor(self.backgroundRole(), QtCore.Qt.white)
+        self.setPalette(p)
+
+
+        self.plotCanvas = PlaneCanvas(self.planes, self.indexes, axis_indexes, self.dataset_title, self.default_cmap,
+                                      display_horizontal_indicator=self.show_h_indicator,
+                                      display_vertical_indicator=self.show_v_indicator, v_min_max=v_min_max)
+
+        self.layout = QtGui.QVBoxLayout(self)
+        self.layout.addWidget(self.plotCanvas)
+
+    def set_cmap(self, action):
+        self.plotCanvas.set_colormap(str(action))
+
+    def set_vertical_line_indicator(self, line):
+        self.plotCanvas.set_vertical_line_indicator(line)
+
+    def set_horizontal_line_indicator(self, line):
+        self.plotCanvas.set_horizontal_line_indicator(line)
+
+
+class TopMenu(QtGui.QMenuBar):
+    def __init__(self, parent, colormap_monitor):
+        super(QtGui.QMenuBar, self).__init__(parent)
+
+        self.fileMenu = self.addMenu('&File')
+        exitAction = QtGui.QAction('&Exit', self)
+        self.fileMenu.addAction(exitAction)
+
+        self.viewMenu = self.addMenu('&View')
+        self.colormapMenu = self.viewMenu.addMenu("&Colormap")
+
+        self.colormap_monitor = colormap_monitor
+
+        self.colormap_monitor.cmap_changed.connect(self.set_selected_cmap)
+
+        def colormapChanger(color_map_name):
+            def performColorMapChange():
+                self.colormap_monitor.colormapUpdated(color_map_name)
+            return performColorMapChange
+
+        for item in ['seismic', 'spectral', 'RdGy', 'hot', 'jet', 'gray']:
+            action = self.colormapMenu.addAction(item)
+            action.setCheckable(True)
+            action.triggered.connect(colormapChanger(item))
+
+    def set_selected_cmap(self, cmap_name):
+        for item in self.colormapMenu.actions():
+            item.setChecked(str(item.text()) == cmap_name)
+
+
+class LineSelector(QtGui.QWidget):
+    indexChanged = QtCore.pyqtSignal(int)
+
+    def __init__(self, parent, label, indexes, monitor_func):
+        super(QtGui.QWidget, self).__init__(parent)
+        self.label = label
+        self.indexes = indexes
+        self.monitor_func = monitor_func
+
+        self.layout = QtGui.QHBoxLayout()
+        self.slabel = QtGui.QLabel(self.label)
+        self.sbox = QtGui.QSpinBox(self)
+        self.sbox.setRange(self.indexes[0], self.indexes[-1])
+        self.sbox.valueChanged.connect(self.monitor_func)
+        self.layout.addWidget(self.slabel)
+        self.layout.addWidget(self.sbox)
+        self.setLayout(self.layout)
+
+    def index_changed(self, val):
+        self.indexChanged.emit(val)
+
+    def set_index(self, val):
+        self.sbox.blockSignals(True)
+        self.sbox.setValue(val)
+        self.sbox.blockSignals(False)
+
+
+class ToolBar(QtGui.QToolBar):
+    def __init__(self, xline_indexes, iline_indexes, depth_indexes, line_selection_monitor):
+        super(ToolBar, self).__init__("")
+        self.xline_indexes = xline_indexes
+        self.iline_indexes = iline_indexes
+        self.depth_indexes = depth_indexes
+        self.line_selection_monitor = line_selection_monitor
+
+        # xline
+        self.xline_selector = LineSelector(self, "xline", self.xline_indexes, self.line_selection_monitor.xlineUpdated)
+        self.line_selection_monitor.xlineChanged.connect(self.xline_selector.set_index)
+        self.addWidget(self.xline_selector)
+
+        # iline
+        self.iline_selector = LineSelector(self, "iline", self.iline_indexes, self.line_selection_monitor.ilineUpdated)
+        self.line_selection_monitor.ilineChanged.connect(self.iline_selector.set_index)
+        self.addWidget(self.iline_selector)
+
+        # iline
+        self.depth_selector = LineSelector(self, "depth", self.depth_indexes, self.line_selection_monitor.depthUpdated)
+        self.addWidget(self.depth_selector)
+
+
+class AppWindow(QtGui.QMainWindow):
+    def __init__(self, s):
+        QtGui.QMainWindow.__init__(self)
+        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
+        self.setWindowTitle("Segy Viewer")
+        self.main_widget = QtGui.QWidget(self)
+
+        # signal monitors
+        colormap_monitor = ColorMapMonitor(self)
+        line_monitor = LineSelectionMonitor(self)
+
+        self.setMenuBar(TopMenu(self, colormap_monitor))
+        self.addToolBar(ToolBar(s.xlines, s.ilines, range(s.samples), line_monitor))
+        self.statusBar()
+
+        depth_planes, min_max = read_traces_to_memory(s)
+
+        # initialize
+        x_plane_canvas = PlotWidget(s.xline, s.xlines, (s.ilines, 0), "xlines", show_v_indicator=True, v_min_max=min_max)
+        i_plane_canvas = PlotWidget(s.iline, s.ilines, (s.xlines, 0), "ilines", show_v_indicator=True, v_min_max=min_max)
+        depth_plane_canvas = PlotWidget(depth_planes, range(s.samples), (s.xlines, s.ilines), "depth",
+                                        show_v_indicator=True, show_h_indicator=True, v_min_max=min_max)
+
+        # attach signals
+        x_plane_canvas.plotCanvas.indexChanged.connect(line_monitor.ilineUpdated)
+        i_plane_canvas.plotCanvas.indexChanged.connect(line_monitor.xlineUpdated)
+
+        line_monitor.ilineChanged.connect(x_plane_canvas.set_vertical_line_indicator)
+        line_monitor.ilineChanged.connect(depth_plane_canvas.set_horizontal_line_indicator)
+        line_monitor.ilineChanged.connect(i_plane_canvas.plotCanvas.update_image)
+
+        line_monitor.xlineChanged.connect(i_plane_canvas.set_vertical_line_indicator)
+        line_monitor.xlineChanged.connect(depth_plane_canvas.set_vertical_line_indicator)
+        line_monitor.xlineChanged.connect(x_plane_canvas.plotCanvas.update_image)
+
+        line_monitor.depthChanged.connect(depth_plane_canvas.plotCanvas.update_image)
+
+        # colormap signals
+        colormap_monitor.cmap_changed.connect(x_plane_canvas.set_cmap)
+        colormap_monitor.cmap_changed.connect(i_plane_canvas.set_cmap)
+        colormap_monitor.cmap_changed.connect(depth_plane_canvas.set_cmap)
+
+        # layout
+        xdock = QtGui.QDockWidget("x-lines")
+        xdock.setFeatures(QtGui.QDockWidget.DockWidgetFloatable | QtGui.QDockWidget.DockWidgetMovable)
+        xdock.setWidget(x_plane_canvas)
+
+        idock = QtGui.QDockWidget("i-lines")
+        idock.setFeatures(QtGui.QDockWidget.DockWidgetFloatable | QtGui.QDockWidget.DockWidgetMovable)
+        idock.setWidget(i_plane_canvas)
+
+        ddock = QtGui.QDockWidget("depth plane")
+        ddock.setFeatures(QtGui.QDockWidget.DockWidgetFloatable | QtGui.QDockWidget.DockWidgetMovable)
+        ddock.setWidget(depth_plane_canvas)
+
+        self.setDockOptions(QtGui.QMainWindow.AllowNestedDocks)
+        self.addDockWidget(QtCore.Qt.TopDockWidgetArea, xdock)
+        self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, idock)
+        self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, ddock)
+
+        self.main_widget.setFocus()
+        self.setCentralWidget(self.main_widget)
+        self.main_widget.hide()
+
+
+def read_traces_to_memory(segy):
+    ''' read all samples into memory and identify min and max'''
+
+    all_traces = np.empty(shape=((len(segy.ilines) * len(segy.xlines)), segy.samples), dtype=np.float32)
+
+    min_value = sys.float_info.max
+    max_value = sys.float_info.min
+
+    for i, t in enumerate(segy.trace):
+        all_traces[i] = t
+
+        local_min = np.nanmin(t)
+        local_max = np.nanmax(t)
+
+        if np.isfinite(local_min):
+            min_value = min(local_min, min_value)
+
+        if np.isfinite(local_max):
+            max_value = max(local_max, max_value)
+
+    all_traces2 = all_traces.reshape(len(segy.ilines), len(segy.xlines), segy.samples)
+
+    transposed_traces = all_traces2.transpose(2, 0, 1)
+
+    return transposed_traces, (min_value,max_value)
+
+
+
+
+def main():
+    if len(sys.argv) < 2:
+        sys.exit("Usage: segyviewer.py [file]")
+
+    filename = sys.argv[1]
+
+    with segyio.open(filename, "r") as s:
+        qApp = QtGui.QApplication(sys.argv)
+        aw = AppWindow(s)
+        aw.show()
+        sys.exit(qApp.exec_())
+
+
+if __name__ == '__main__':
+    main()

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/segyio.git



More information about the debian-science-commits mailing list