[segyio] 76/376: Adding filehandling to viewer
Jørgen Kvalsvik
jokva-guest at moszumanska.debian.org
Wed Sep 20 08:04:10 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 9763fb3b06ad596ca672d7a5b707f477f0794175
Author: Thorvald Johannessen <thorvjo at statoil.com>
Date: Wed Oct 19 17:21:24 2016 +0200
Adding filehandling to viewer
---
applications/segyviewer.py | 333 +++++++++++++++++++++++++++++----------
python/segyview/CMakeLists.txt | 2 +-
python/segyview/__init__.py | 3 +-
python/segyview/segyiowrapper.py | 147 +++++++++++++++++
python/segyview/segyplot.py | 1 +
python/segyview/slicewidget.py | 24 ++-
python/segyview/util.py | 36 -----
tests/test_segyview.py | 14 +-
8 files changed, 434 insertions(+), 126 deletions(-)
diff --git a/applications/segyviewer.py b/applications/segyviewer.py
index c60d7ea..21b0807 100755
--- a/applications/segyviewer.py
+++ b/applications/segyviewer.py
@@ -1,10 +1,9 @@
#!/usr/bin/env python
import sys
-import segyio
+
from PyQt4 import QtGui, QtCore
from segyview import *
-from segyview import util
class LineSelectionMonitor(QtCore.QObject):
@@ -35,127 +34,299 @@ class ColorMapMonitor(QtCore.QObject):
self.cmap_changed.emit(str(value))
-def configure_main_menu(menu, colormap_monitor, available_colormaps):
- menu.fileMenu = menu.addMenu('&File')
- exitAction = QtGui.QAction('&Exit', menu)
- menu.fileMenu.addAction(exitAction)
+class FileActivityMonitor(QtCore.QObject):
+ started = QtCore.pyqtSignal()
+ finished = QtCore.pyqtSignal()
+ cancelled_operation = False
+
+ def __init__(self, parent=None):
+ QtCore.QObject.__init__(self)
+ self.cancelled_operation = False
+
+ def reset(self):
+ self.cancelled_operation = False
+
+ def set_file_read_started(self):
+ self.started.emit()
+
+ def set_file_read_finished(self):
+ self.finished.emit()
+
+ def set_cancel_operation(self):
+ self.finished.emit()
+ self.cancelled_operation = True
+
- menu.viewMenu = menu.addMenu('&View')
- menu.colormapMenu = menu.viewMenu.addMenu("&Colormap")
+class ProgressWidget(QtGui.QWidget):
- def set_selected_cmap(cmap_name):
- for item in menu.colormapMenu.actions():
- item.setChecked(str(item.text()) == cmap_name)
+ def __init__(self, call_on_cancel):
+ super(ProgressWidget, self).__init__()
+ self.call_on_cancel = call_on_cancel
- colormap_monitor.cmap_changed.connect(set_selected_cmap)
+ layout = QtGui.QHBoxLayout()
+ # progress bar
+ self.p_bar = QtGui.QProgressBar(self)
+ cancel_file_load_btn = QtGui.QPushButton()
+ cancel_file_load_btn.setText("cancel")
- def colormap_changer(color_map_name):
- def perform_colormap_change():
- colormap_monitor.colormap_updated(color_map_name)
+ cancel_file_load_btn.clicked.connect(self.call_on_cancel)
- return perform_colormap_change
+ layout.addWidget(self.p_bar, 2)
+ layout.addWidget(cancel_file_load_btn)
- for item in available_colormaps:
- action = menu.colormapMenu.addAction(item)
- action.setCheckable(True)
- action.triggered.connect(colormap_changer(item))
+ self.setLayout(layout)
+
+ def set_value(self, int):
+ self.p_bar.setValue(int)
+
+
+class FileLoaderWorker(QtCore.QObject):
+ finished = QtCore.pyqtSignal(int)
+ progress = QtCore.pyqtSignal(int)
+
+ def __init__(self, segy_file_wrapper, filename, read_to_memory=False):
+ QtCore.QObject.__init__(self)
+ self.segy_file_wrapper = segy_file_wrapper
+ self.filename = filename
+ self.read_to_memory = read_to_memory
+
+ def load_file(self):
+ successful_file_open = self.segy_file_wrapper.open_file(self.filename,
+ read_to_memory=self.read_to_memory,
+ progress_callback=self.progress.emit)
+ if successful_file_open:
+ self.finished.emit(0)
+ else:
+ self.finished.emit(1)
+
+ return None
class SegyViewer(QtGui.QMainWindow):
- def __init__(self, s):
+ def __init__(self, filename):
QtGui.QMainWindow.__init__(self)
+
+ # qthreads needs to be in scope of main thread to not be "accidentally" garbage collected
+ self.file_loader_thread = None
+ self.file_loader_worker = None
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
- self.setWindowTitle("SegyViewer")
- main_widget = QtGui.QWidget(self)
# signal monitors
- colormap_monitor = ColorMapMonitor(self)
- line_monitor = LineSelectionMonitor(self)
+ self.colormap_monitor = ColorMapMonitor(self)
+ self.line_monitor = LineSelectionMonitor(self)
+ self.file_activity_monitor = FileActivityMonitor(self)
+
+ # the wrapper around segyio
+ self.swrap = SegyIOWrapper(self.file_activity_monitor)
# menus
available_colormaps = ['seismic', 'spectral', 'RdGy', 'hot', 'jet', 'gray']
- configure_main_menu(self.menuBar(), colormap_monitor, available_colormaps)
+ self.configure_main_menu(self.menuBar(), self.colormap_monitor, available_colormaps)
+
+ # layout
+ self.setWindowTitle("SegyViewer")
+ self.xdock = QtGui.QDockWidget("x-line")
+ self.xdock.setFeatures(QtGui.QDockWidget.DockWidgetFloatable | QtGui.QDockWidget.DockWidgetMovable)
+
+ self.idock = QtGui.QDockWidget("i-line")
+ self.idock.setFeatures(QtGui.QDockWidget.DockWidgetFloatable | QtGui.QDockWidget.DockWidgetMovable)
+
+ self.ddock = QtGui.QDockWidget("depth slice")
+ self.ddock.setFeatures(QtGui.QDockWidget.DockWidgetFloatable | QtGui.QDockWidget.DockWidgetMovable)
+ self.setup_dock_widgets()
+
+ # progress bar
+ self.progress_bar = ProgressWidget(self.swrap.file_activity_monitor.set_cancel_operation)
+ self.statusBar().addWidget(self.progress_bar, 1)
+ self.progress_bar.hide()
+
+ #set up an initial size
+ self.resize(1200, 800)
+
+ # connect cursor overrides to file activity that might take long time
+ self.swrap.file_activity_monitor.started.connect(
+ lambda: QtGui.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.BusyCursor)))
+ self.swrap.file_activity_monitor.finished.connect(
+ lambda: QtGui.QApplication.restoreOverrideCursor())
+
+ # initiate the first file load
+ if filename:
+ self.load_file_and_setup_slice_widgets(filename)
+
+ # fix for making dock widgets fill entire window
+ # self.main_widget = QtGui.QWidget(self)
+ # self.main_widget.setFocus()
+ # self.setCentralWidget(self.main_widget)
+ # self.main_widget.hide()
+
+ def setup_dock_widgets(self):
+ self.setDockOptions(QtGui.QMainWindow.AllowNestedDocks)
+ self.addDockWidget(QtCore.Qt.TopDockWidgetArea, self.xdock)
+ self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.idock)
+ self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.ddock)
+
+ def configure_main_menu(self, menu, colormap_monitor, available_colormaps):
+ menu.fileMenu = menu.addMenu('&File')
- self.addToolBar(LineNavigationBar(s.xlines, s.ilines, range(s.samples), line_monitor))
- self.statusBar()
+ exitAction = QtGui.QAction('&Exit', menu)
+ menu.fileMenu.addAction(exitAction)
- # to avoid having to rescan the entire file for accessing each depth slice. all slices are read once.
- depth_slices, min_max = util.read_traces_to_memory(s)
+ openAction = QtGui.QAction('&Open', menu)
+ openAction.setShortcut("Ctrl+O")
+ menu.fileMenu.addAction(openAction)
+ openAction.triggered.connect(self.open_file_dialogue)
- # initialize
- x_slice_widget = SliceWidget(s.xline, s.xlines,
- x_axis_indexes=('i-lines', s.ilines.tolist()),
- y_axis_indexes=('depth', range(s.samples)),
+ menu.viewMenu = menu.addMenu('&View')
+ menu.colormapMenu = menu.viewMenu.addMenu("&Colormap")
+
+ def set_selected_cmap(cmap_name):
+ for item in menu.colormapMenu.actions():
+ item.setChecked(str(item.text()) == cmap_name)
+
+ colormap_monitor.cmap_changed.connect(set_selected_cmap)
+
+ def colormap_changer(color_map_name):
+ def perform_colormap_change():
+ colormap_monitor.colormap_updated(color_map_name)
+
+ return perform_colormap_change
+
+ for item in available_colormaps:
+ action = menu.colormapMenu.addAction(item)
+ action.setCheckable(True)
+ action.triggered.connect(colormap_changer(item))
+
+ def remove_all_slice_widgets(self):
+ # removing old widgets
+ for tbar in self.findChildren(QtGui.QToolBar):
+ self.removeToolBar(tbar)
+
+ # removing old slice widgets from dock widgets
+ for dock_widget in self.findChildren(QtGui.QDockWidget):
+ for widgt in dock_widget.findChildren(SliceWidget):
+ widgt.deleteLater()
+
+ def setup_widgets_and_controls(self):
+ self.addToolBar(LineNavigationBar(self.swrap.xlines,
+ self.swrap.ilines,
+ range(self.swrap.samples),
+ self.line_monitor))
+
+ # initialize slice widgets
+ x_slice_widget = SliceWidget(self.swrap.xline, self.swrap.xlines,
+ x_axis_indexes=('i-lines', self.swrap.ilines),
+ y_axis_indexes=('depth', range(self.swrap.samples)),
show_v_indicator=True,
- v_min_max=min_max)
+ v_min_max=self.swrap.min_max)
- i_slice_widget = SliceWidget(s.iline, s.ilines,
- x_axis_indexes=('x-lines', s.xlines.tolist()),
- y_axis_indexes=('depth', range(s.samples)),
+ i_slice_widget = SliceWidget(self.swrap.iline, self.swrap.ilines,
+ x_axis_indexes=('x-lines', self.swrap.xlines),
+ y_axis_indexes=('depth', range(self.swrap.samples)),
show_v_indicator=True,
- v_min_max=min_max)
+ v_min_max=self.swrap.min_max)
- depth_slice_widget = SliceWidget(depth_slices, range(s.samples),
- x_axis_indexes=('i-lines', s.ilines.tolist()),
- y_axis_indexes=('x-lines', s.xlines.tolist()),
+ depth_slice_widget = SliceWidget(self.swrap.depth_slice, range(self.swrap.samples),
+ x_axis_indexes=('i-lines', self.swrap.ilines),
+ y_axis_indexes=('x-lines', self.swrap.xlines),
show_v_indicator=True,
show_h_indicator=True,
- v_min_max=min_max)
+ v_min_max=self.swrap.min_max)
# attach line-index change signals
- x_slice_widget.index_changed.connect(line_monitor.iline_updated)
- i_slice_widget.index_changed.connect(line_monitor.xline_updated)
+ x_slice_widget.index_changed.connect(self.line_monitor.iline_updated)
+ i_slice_widget.index_changed.connect(self.line_monitor.xline_updated)
- line_monitor.iline_changed.connect(x_slice_widget.set_vertical_line_indicator)
- line_monitor.iline_changed.connect(depth_slice_widget.set_vertical_line_indicator)
- line_monitor.iline_changed.connect(i_slice_widget.update_image)
+ self.line_monitor.iline_changed.connect(x_slice_widget.set_vertical_line_indicator)
+ self.line_monitor.iline_changed.connect(depth_slice_widget.set_vertical_line_indicator)
+ self.line_monitor.iline_changed.connect(i_slice_widget.update_image)
- line_monitor.xline_changed.connect(i_slice_widget.set_vertical_line_indicator)
- line_monitor.xline_changed.connect(depth_slice_widget.set_horizontal_line_indicator)
- line_monitor.xline_changed.connect(x_slice_widget.update_image)
+ self.line_monitor.xline_changed.connect(i_slice_widget.set_vertical_line_indicator)
+ self.line_monitor.xline_changed.connect(depth_slice_widget.set_horizontal_line_indicator)
+ self.line_monitor.xline_changed.connect(x_slice_widget.update_image)
- line_monitor.depth_changed.connect(depth_slice_widget.update_image)
+ self.line_monitor.depth_changed.connect(depth_slice_widget.update_image)
# colormap signals
- colormap_monitor.cmap_changed.connect(x_slice_widget.set_cmap)
- colormap_monitor.cmap_changed.connect(i_slice_widget.set_cmap)
- colormap_monitor.cmap_changed.connect(depth_slice_widget.set_cmap)
+ self.colormap_monitor.cmap_changed.connect(x_slice_widget.set_cmap)
+ self.colormap_monitor.cmap_changed.connect(i_slice_widget.set_cmap)
+ self.colormap_monitor.cmap_changed.connect(depth_slice_widget.set_cmap)
- # layout
- xdock = QtGui.QDockWidget("x-line")
- xdock.setFeatures(QtGui.QDockWidget.DockWidgetFloatable | QtGui.QDockWidget.DockWidgetMovable)
- xdock.setWidget(x_slice_widget)
+ self.xdock.setWidget(x_slice_widget)
+ self.idock.setWidget(i_slice_widget)
+ self.ddock.setWidget(depth_slice_widget)
- idock = QtGui.QDockWidget("i-line")
- idock.setFeatures(QtGui.QDockWidget.DockWidgetFloatable | QtGui.QDockWidget.DockWidgetMovable)
- idock.setWidget(i_slice_widget)
+ def open_file_dialogue(self):
- ddock = QtGui.QDockWidget("depth slice")
- ddock.setFeatures(QtGui.QDockWidget.DockWidgetFloatable | QtGui.QDockWidget.DockWidgetMovable)
- ddock.setWidget(depth_slice_widget)
+ f_dialog = QtGui.QFileDialog(self)
+ f_dialog.setViewMode(QtGui.QFileDialog.Detail)
+ f_dialog.setNameFilter("Segy File (*.seg *.segy *.sgy)")
+ load_to_memory_label = QtGui.QLabel("Read entire Segy file to memory")
+ load_to_memory_cbox = QtGui.QCheckBox()
+ load_to_memory_cbox.setChecked(True)
+ layout = f_dialog.layout()
+ layout.addWidget(load_to_memory_label)
+ layout.addWidget(load_to_memory_cbox)
- self.setDockOptions(QtGui.QMainWindow.AllowNestedDocks)
- self.addDockWidget(QtCore.Qt.TopDockWidgetArea, xdock)
- self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, idock)
- self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, ddock)
+ def file_selected(filename):
- main_widget.setFocus()
- self.setCentralWidget(main_widget)
- main_widget.hide()
+ if filename:
+ self.load_file_and_setup_slice_widgets(filename, read_to_memory=load_to_memory_cbox.isChecked())
+ f_dialog.fileSelected.connect(file_selected)
-def main():
- if len(sys.argv) < 2:
- sys.exit("Usage: segyviewer.py [file]")
+ f_dialog.show()
+
+ #filename = f_dialog.getOpenFileName(None, "Open Segy File", filter="Segy file (*.seg *.segy *.sgy)")
+
+ def load_file_and_setup_slice_widgets(self, filename, read_to_memory=True):
+ #remove old widgets
+ self.remove_all_slice_widgets()
+
+ # progress bar
+ self.progress_bar.show()
- filename = sys.argv[1]
+ self.file_activity_monitor.reset()
+ self.swrap = SegyIOWrapper(self.file_activity_monitor)
- with segyio.open(filename, "r") as s:
- q_app = QtGui.QApplication(sys.argv)
- segy_viewer = SegyViewer(s)
- segy_viewer.show()
- sys.exit(q_app.exec_())
+ # worker thread and worker obj are referenced from main thread to not get gc'ed by accident
+ self.file_loader_thread = QtCore.QThread()
+ self.file_loader_worker = FileLoaderWorker(self.swrap, filename, read_to_memory=read_to_memory)
+ self.file_loader_worker.moveToThread(self.file_loader_thread)
+ # what to do
+ self.file_loader_thread.started.connect(self.file_loader_worker.load_file)
+
+ # update progress
+ self.file_loader_worker.progress.connect(self.progress_bar.set_value)
+
+ # when finished
+ self.file_loader_worker.finished.connect(self.complete_finished_file_load_operation)
+
+ self.file_loader_thread.start()
+
+ def complete_finished_file_load_operation(self, status):
+
+ if status == 0: # when completed successfully
+ self.setup_widgets_and_controls()
+
+ self.progress_bar.hide()
+ self.file_loader_thread.quit()
+
+
+def main():
+
+ filename = None
+ if len(sys.argv) == 2:
+ filename = sys.argv[1]
+
+ q_app = QtGui.QApplication(sys.argv)
+ segy_viewer = SegyViewer(filename)
+ segy_viewer.show()
+ sys.exit(q_app.exec_())
if __name__ == '__main__':
main()
+
+
+
+
diff --git a/python/segyview/CMakeLists.txt b/python/segyview/CMakeLists.txt
index ec81844..42de12b 100644
--- a/python/segyview/CMakeLists.txt
+++ b/python/segyview/CMakeLists.txt
@@ -1,9 +1,9 @@
set(PYTHON_SOURCES
__init__.py
linenavigationbar.py
+ segyiowrapper.py
segyplot.py
slicewidget.py
- util.py
)
add_python_package(segyview segyview "${PYTHON_SOURCES}")
diff --git a/python/segyview/__init__.py b/python/segyview/__init__.py
index c0e02e1..a8c2648 100644
--- a/python/segyview/__init__.py
+++ b/python/segyview/__init__.py
@@ -1,5 +1,5 @@
from .segyplot import SegyPlot
-import util
+from .segyiowrapper import SegyIOWrapper, SlicesWrapper
try:
from .linenavigationbar import LineNavigationBar
@@ -9,3 +9,4 @@ except ImportError as e:
import traceback
exc_type, exc_value, exc_traceback = sys.exc_info()
traceback.print_exception(exc_type, exc_value, exc_traceback, limit=2, file=sys.stderr)
+
diff --git a/python/segyview/segyiowrapper.py b/python/segyview/segyiowrapper.py
new file mode 100644
index 0000000..2350c67
--- /dev/null
+++ b/python/segyview/segyiowrapper.py
@@ -0,0 +1,147 @@
+import sys
+import numpy as np
+from numpy import inf
+import segyio
+
+class SlicesWrapper(object):
+ """ Simple wrapper either around the Line class (when read_from_file) or a native Numpy array in memory.
+ (by. mapping index to line number).
+
+ Will signal file read start and finished events through the FileActivityMonitor when file read operations in
+ segyio api are used.
+ """
+
+ def __init__(self, segyiowrapper, indexes, cube, read_from_file=False):
+ self.indexes = indexes
+ self.cube = cube
+ self.swrap = segyiowrapper
+ self.read_from_file = read_from_file
+
+ def __getitem__(self, item):
+
+ if self.read_from_file:
+ self.swrap.file_activity_monitor.set_file_read_started()
+ slice_from_file = self.cube[item]
+ self.swrap.file_activity_monitor.set_file_read_finished()
+ return slice_from_file
+ else:
+ return self.cube[self.indexes.index(item)]
+
+ def __len__(self):
+ return len(self.indexes)
+
+
+class SegyIOWrapper(object):
+ """ Wraps around the functionality offered by the segyio api - and proxies read operations either towards segyio,
+ or an in-memory numpy array.
+ """
+
+ def __init__(self, file_activity_monitor=None):
+ self.s, self.iline_slices, self.xline_slices, self.depth_slices, self.min_max = None, None, None, None, None
+ self.file_activity_monitor = file_activity_monitor
+
+ def open_file(self, filename, read_to_memory=True, progress_callback=None):
+ """ to avoid having to rescan the entire file for accessing each depth slice.
+ we have the option that all traces are read once. Use the read_to_memory flag for that intention.
+ """
+
+ # close the current file.
+ if self.s is not None:
+ self.s.close()
+
+ self.s = segyio.open(str(filename))
+
+ if read_to_memory:
+ return self.read_traces_to_memory(progress_callback=progress_callback)
+ else:
+ self.iline_slices = SlicesWrapper(self, self.s.ilines.tolist(), self.s.iline, read_from_file=True)
+ self.xline_slices = SlicesWrapper(self, self.s.xlines.tolist(), self.s.xline, read_from_file=True)
+ self.depth_slices = SlicesWrapper(self, range(self.s.samples), self.s.depth_slice, read_from_file=True)
+ self.min_max = None
+ if progress_callback is not None:
+ progress_callback(100)
+ return True
+
+ def read_traces_to_memory(self, progress_callback=None):
+ """ Read all traces into memory and identify global min and max values.
+
+ Utility method to handle the challenge of navigating up and down in depth slices,
+ as each depth slice consist of samples from all traces in the segy file.
+
+ The cubes created are transposed in aspect of the iline, xline and depth plane. Where each slice of the
+ returned depth cube consists of all samples for the given depth, oriented by [iline, xline]
+
+ Returns True if operation was able to run to completion. False if actively cancelled, or disrupted in any
+ other way.
+ """
+
+ all_traces = np.empty(shape=((len(self.s.ilines) * len(self.s.xlines)), self.s.samples), dtype=np.single)
+
+ number_of_traces = self.s.tracecount
+
+ # signal file read start to anyone listening to the monitor
+ if self.file_activity_monitor is not None:
+ self.file_activity_monitor.set_file_read_started()
+
+ for i, t in enumerate(self.s.trace):
+
+ if self.file_activity_monitor is not None and self.file_activity_monitor.cancelled_operation:
+ """ Read operation is cancelled, closing segy file, and signal that file read is finished
+ """
+ self.s.close()
+ self.file_activity_monitor.set_file_read_finished()
+ return False
+
+ all_traces[i] = t
+
+ if progress_callback is not None:
+ progress_callback((float(i + 1) / number_of_traces) * 100)
+
+ if self.file_activity_monitor is not None:
+ self.file_activity_monitor.set_file_read_finished()
+
+ iline_slices = all_traces.reshape(len(self.s.ilines), len(self.s.xlines), self.s.samples)
+ xline_slices = iline_slices.transpose(1, 0, 2)
+
+ self.depth_slices = iline_slices.transpose(2, 0, 1)
+
+ self.iline_slices = SlicesWrapper(self, self.s.ilines.tolist(), iline_slices, read_from_file=False)
+ self.xline_slices = SlicesWrapper(self, self.s.xlines.tolist(), xline_slices, read_from_file=False)
+ self.min_max = self.identify_min_max(all_traces)
+ return True
+
+
+ def identify_min_max(self, all_traces):
+
+ # removing positive and negative infinite numbers
+ all_traces[all_traces == inf] = 0
+ all_traces[all_traces == -inf] = 0
+
+ min_value = np.nanmin(all_traces)
+ max_value = np.nanmax(all_traces)
+
+ return (min_value, max_value)
+
+ @property
+ def samples(self):
+ return self.s.samples
+
+ @property
+ def xlines(self):
+ return self.s.xlines.tolist()
+
+ @property
+ def ilines(self):
+ return self.s.ilines.tolist()
+
+ @property
+ def iline(self):
+ return self.iline_slices
+
+ @property
+ def xline(self):
+ return self.xline_slices
+
+ @property
+ def depth_slice(self):
+ return self.depth_slices
\ No newline at end of file
diff --git a/python/segyview/segyplot.py b/python/segyview/segyplot.py
index 9848093..1e46df5 100644
--- a/python/segyview/segyplot.py
+++ b/python/segyview/segyplot.py
@@ -54,6 +54,7 @@ class SegyPlot(object):
vmin=self.vmin,
vmax=self.vmax)
+
if display_vertical_indicator:
self.vertical_indicator_rect = self.slice_axes.add_patch(
patches.Rectangle(
diff --git a/python/segyview/slicewidget.py b/python/segyview/slicewidget.py
index 968d30c..f669f66 100644
--- a/python/segyview/slicewidget.py
+++ b/python/segyview/slicewidget.py
@@ -34,6 +34,8 @@ class SliceWidget(QtGui.QWidget):
# setting up the figure and canvas
self.figure = Figure(figsize=(800, 200), dpi=20, facecolor='white')
+
+
self.axes = self.figure.add_subplot(111)
self.segy_plot = SegyPlot(self.slices,
@@ -65,7 +67,6 @@ class SliceWidget(QtGui.QWidget):
if self.x_axis_indexes is not None:
self.index_changed.emit(self.x_axis_indexes[x])
-
def update_image(self, index):
self.segy_plot.update_image(index)
self.figure_canvas.draw()
@@ -81,3 +82,24 @@ class SliceWidget(QtGui.QWidget):
def set_horizontal_line_indicator(self, line):
self.segy_plot.set_horizontal_line_indicator(line)
self.figure_canvas.draw()
+
+ def toggle_disabled_state(self):
+
+ self.overlay = Overlay(self)
+ self.overlay.setGeometry(self.layout.geometry())
+ self.overlay.show()
+
+
+
+class Overlay(QtGui.QWidget):
+ def __init__(self, parent):
+ super(Overlay, self).__init__(parent)
+ self.parent = parent
+ def paintEvent(self, QPaintEvent):
+
+ painter = QtGui.QPainter(self)
+
+ color = QtGui.QColor(0,0,0,50)
+ painter.fillRect(self.rect(), color)
+
+
diff --git a/python/segyview/util.py b/python/segyview/util.py
deleted file mode 100644
index 47a4c4e..0000000
--- a/python/segyview/util.py
+++ /dev/null
@@ -1,36 +0,0 @@
-import sys
-import numpy as np
-
-
-def read_traces_to_memory(segy):
- """ Read all traces into memory and identify global min and max values.
-
- Utility method to handle the challenge of navigating up and down in depth slices,
- as each depth slice consist of samples from all traces in the segy file.
-
- The cube returned is transposed in aspect of the depth plane. Where each slice of the returned array
- consists of all samples for the given depth, oriented by [iline, xline]
- """
-
- 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)
-
- reshaped_traces = all_traces.reshape(len(segy.ilines), len(segy.xlines), segy.samples)
-
- transposed_traces = reshaped_traces.transpose(2, 0, 1)
-
- return transposed_traces, (min_value, max_value)
diff --git a/tests/test_segyview.py b/tests/test_segyview.py
index ea4d188..fa027a3 100644
--- a/tests/test_segyview.py
+++ b/tests/test_segyview.py
@@ -1,6 +1,6 @@
from unittest import TestCase
import segyio
-import segyview.util as util
+from segyview import SegyIOWrapper
import itertools
@@ -11,15 +11,17 @@ class TestSegyView(TestCase):
def test_read_all_traces_to_memory_compare_with_depth_slice_and_verify_cube_rotation(self):
- with segyio.open(self.filename, "r") as segy:
- depth_slices, min_max = util.read_traces_to_memory(segy)
+ swrap = SegyIOWrapper()
- for i, slice in enumerate(depth_slices):
+ with segyio.open(self.filename, "r") as segy:
+ swrap.s = segy
+ swrap.read_traces_to_memory()
+ for i, depth_slice in enumerate(swrap.depth_slices):
for ilno, xlno in itertools.product(range(len(segy.ilines)), range(len(segy.xlines))):
- self.assertEqual(slice[ilno, xlno], segy.depth_slice[i][ilno, xlno],
+ self.assertEqual(depth_slice[ilno, xlno], segy.depth_slice[i][ilno, xlno],
"the cube values from read_all_traces and depth_slice differ {0} != {1}"
- .format(slice[ilno, xlno], segy.depth_slice[i][ilno, xlno]))
+ .format(depth_slice[ilno, xlno], segy.depth_slice[i][ilno, xlno]))
--
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