@ -36,11 +36,12 @@ from .util import (ValControl, LinValControl, Marker, EventMarker,
PhaseMarker , make_QPolygonF , draw_label , Label ,
Progressbars )
from PyQt4 import QtCore as qc
from PyQt4 import QtGui as qg
from PyQt4 import QtOpenGL as qgl
from PyQt4 import QtSvg as qsvg
# from PyQt4.QtSvg import *
from PyQt5 import QtCore as qc
from PyQt5 import QtGui as qg
from PyQt5 import QtWidgets as qw
from PyQt5 import QtOpenGL as qgl
from PyQt5 import QtSvg as qsvg
# from PyQt5.QtSvg import *
import scipy . stats as sstats
import platform
@ -49,10 +50,10 @@ if sys.version_info[0] >= 3:
qc . QString = str
if platform . mac_ver ( ) != ( ' ' , ( ' ' , ' ' , ' ' ) , ' ' ) :
qfiledialog_options = qg . QFileDialog . DontUseNativeDialog
qfiledialog_options = qw . QFileDialog . DontUseNativeDialog
macosx = True
else :
qfiledialog_options = qg . QFileDialog . DontUseSheet
qfiledialog_options = qw . QFileDialog . DontUseSheet
macosx = False
logger = logging . getLogger ( ' pyrocko.gui.pile_viewer ' )
@ -537,7 +538,7 @@ class TimeAx(TimeScaler):
ushift = 0.
for l0x in ( l0 , l0_brief , ' ' ) :
label0 = qc . QString ( l0x )
label0 = l0x
rect0 = fm . boundingRect ( label0 )
if rect0 . width ( ) < = pinc_approx * 0.9 :
break
@ -552,7 +553,7 @@ class TimeAx(TimeScaler):
vmin + rect0 . height ( ) + ticklen ) , label0 )
if l1 :
label1 = qc . QString ( l1 )
label1 = l1
rect1 = fm . boundingRect ( label1 )
if uumin + pad < umin - rect1 . width ( ) / 2. and \
umin + rect1 . width ( ) / 2. < uumax - pad :
@ -565,7 +566,7 @@ class TimeAx(TimeScaler):
l1_hits + = 1
if l2 :
label2 = qc . QString ( l2 )
label2 = l2
rect2 = fm . boundingRect ( label2 )
if uumin + pad < umin - rect2 . width ( ) / 2. and \
umin + rect2 . width ( ) / 2. < uumax - pad :
@ -592,7 +593,7 @@ class TimeAx(TimeScaler):
l1 = None
if l1_hits == 0 and l1 :
label1 = qc . QString ( l1 )
label1 = l1
rect1 = fm . boundingRect ( label1 )
p . drawText ( qc . QPointF (
uumin + pad ,
@ -602,7 +603,7 @@ class TimeAx(TimeScaler):
l1_hits + = 1
if l2_hits == 0 and l2 :
label2 = qc . QString ( l2 )
label2 = l2
rect2 = fm . boundingRect ( label2 )
p . drawText ( qc . QPointF (
uumin + pad ,
@ -656,14 +657,14 @@ class Projection(object):
def add_radiobuttongroup ( menu , menudef , obj , target , default = None ) :
group = qg . QActionGroup ( menu )
group = qw . QActionGroup ( menu )
menuitems = [ ]
for l , v in menudef :
k = qg . QAction ( l , menu )
k = qw . QAction ( l , menu )
group . addAction ( k )
menu . addAction ( k )
k . setCheckable ( True )
obj . connect ( group , qc . SIGNAL ( ' triggered(QAction*) ' ) , target )
group . triggered . connect ( target )
menuitems . append ( ( k , v ) )
if default is not None and l == default :
k . setChecked ( True )
@ -701,8 +702,20 @@ def MakePileViewerMainClass(base):
class PileViewerMain ( base ) :
want_input = qc . pyqtSignal ( )
about_to_close = qc . pyqtSignal ( )
pile_has_changed_signal = qc . pyqtSignal ( )
tracks_range_changed = qc . pyqtSignal ( int , int , int )
markers_added = qc . pyqtSignal ( int , int )
markers_removed = qc . pyqtSignal ( int , int )
changed_marker_selection = qc . pyqtSignal ( list )
active_event_marker_changed = qc . pyqtSignal ( int )
def __init__ ( self , pile , ntracks_shown_max , panel_parent , * args ) :
if base == qgl . QGLWidget :
from OpenGL import GL # noqa
base . __init__ (
self , qgl . QGLFormat ( qgl . QGL . SampleBuffers ) , * args )
else :
@ -742,45 +755,43 @@ def MakePileViewerMainClass(base):
self . tax = TimeAx ( )
self . setBackgroundRole ( qg . QPalette . Base )
self . setAutoFillBackground ( True )
poli = qg . QSizePolicy (
qg . QSizePolicy . Expanding ,
qg . QSizePolicy . Expanding )
poli = qw . QSizePolicy (
qw . QSizePolicy . Expanding ,
qw . QSizePolicy . Expanding )
self . setSizePolicy ( poli )
self . setMinimumSize ( 300 , 200 )
self . setFocusPolicy ( qc . Qt . StrongFocus )
self . menu = qg . QMenu ( self )
self . menu = qw . QMenu ( self )
mi = qg . QAction ( ' Open waveform files... ' , self . menu )
mi = qw . QAction ( ' Open waveform files... ' , self . menu )
self . menu . addAction ( mi )
self . connect ( mi , qc . SIGNAL ( " triggered(bool) " ) , self . open_waveforms )
mi . triggered . connect ( self . open_waveforms )
mi = qg . QAction ( ' Open waveform directory... ' , self . menu )
mi = qw . QAction ( ' Open waveform directory... ' , self . menu )
self . menu . addAction ( mi )
self . connect (
mi , qc . SIGNAL ( " triggered(bool) " ) , self . open_waveform_directory )
mi . triggered . connect ( self . open_waveform_directory )
mi = qg . QAction ( ' Open station files... ' , self . menu )
mi = qw . QAction ( ' Open station files... ' , self . menu )
self . menu . addAction ( mi )
self . connect ( mi , qc . SIGNAL ( " triggered(bool) " ) , self . open_stations )
mi . triggered . connect ( self . open_stations )
mi = qg . QAction ( ' Writ e markers...' , self . menu )
mi = qw . QAction ( ' Sav e markers...' , self . menu )
self . menu . addAction ( mi )
self . connect ( mi , qc . SIGNAL ( " triggered(bool) " ) , self . write_markers )
mi . triggered . connect ( self . write_markers )
mi = qg . QAction ( ' Writ e selected markers...' , self . menu )
mi = qw . QAction ( ' Sav e selected markers...' , self . menu )
self . menu . addAction ( mi )
self . connect (
mi , qc . SIGNAL ( " triggered(bool) " ) , self . write_selected_markers )
mi . triggered . connect ( self . write_selected_markers )
mi = qg . QAction ( ' Read markers ...' , self . menu )
mi = qw . QAction ( ' Open marker file ...' , self . menu )
self . menu . addAction ( mi )
self . connect ( mi , qc . SIGNAL ( " triggered(bool) " ) , self . read_markers )
mi . triggered . connect ( self . read_markers )
mi = qg . QAction ( ' Read events ...' , self . menu )
mi = qw . QAction ( ' Open event file ...' , self . menu )
self . menu . addAction ( mi )
self . connect ( mi , qc . SIGNAL ( " triggered(bool) " ) , self . read_events )
mi . triggered . connect ( self . read_events )
self . menu . addSeparator ( )
@ -855,12 +866,10 @@ def MakePileViewerMainClass(base):
self . _ssort = lambda tr : ( )
self . menuitem_distances_3d = qg . QAction ( ' 3D distances ' , self . menu )
self . menuitem_distances_3d = qw . QAction ( ' 3D distances ' , self . menu )
self . menuitem_distances_3d . setCheckable ( True )
self . menuitem_distances_3d . setChecked ( False )
self . connect (
self . menuitem_distances_3d ,
qc . SIGNAL ( " toggled(bool) " ) ,
self . menuitem_distances_3d . toggled . connect (
self . distances_3d_changed )
self . menu . addAction ( self . menuitem_distances_3d )
@ -909,84 +918,84 @@ def MakePileViewerMainClass(base):
self . menu . addSeparator ( )
self . menuitem_antialias = qg . QAction ( ' Antialiasing ' , self . menu )
self . menuitem_antialias = qw . QAction ( ' Antialiasing ' , self . menu )
self . menuitem_antialias . setCheckable ( True )
self . menu . addAction ( self . menuitem_antialias )
self . menuitem_liberal_fetch = qg . QAction (
self . menuitem_liberal_fetch = qw . QAction (
' Liberal Fetch Optimization ' , self . menu )
self . menuitem_liberal_fetch . setCheckable ( True )
self . menu . addAction ( self . menuitem_liberal_fetch )
self . menuitem_cliptraces = qg . QAction ( ' Clip Traces ' , self . menu )
self . menuitem_cliptraces = qw . QAction ( ' Clip Traces ' , self . menu )
self . menuitem_cliptraces . setCheckable ( True )
self . menuitem_cliptraces . setChecked ( True )
self . menu . addAction ( self . menuitem_cliptraces )
self . menuitem_showboxes = qg . QAction ( ' Show Boxes ' , self . menu )
self . menuitem_showboxes = qw . QAction ( ' Show Boxes ' , self . menu )
self . menuitem_showboxes . setCheckable ( True )
self . menuitem_showboxes . setChecked ( True )
self . menu . addAction ( self . menuitem_showboxes )
self . menuitem_colortraces = qg . QAction ( ' Color Traces ' , self . menu )
self . menuitem_colortraces = qw . QAction ( ' Color Traces ' , self . menu )
self . menuitem_colortraces . setCheckable ( True )
self . menuitem_colortraces . setChecked ( False )
self . menu . addAction ( self . menuitem_colortraces )
self . menuitem_showscalerange = qg . QAction (
self . menuitem_showscalerange = qw . QAction (
' Show Scale Ranges ' , self . menu )
self . menuitem_showscalerange . setCheckable ( True )
self . menu . addAction ( self . menuitem_showscalerange )
self . menuitem_showscaleaxis = qg . QAction (
self . menuitem_showscaleaxis = qw . QAction (
' Show Scale Axes ' , self . menu )
self . menuitem_showscaleaxis . setCheckable ( True )
self . menu . addAction ( self . menuitem_showscaleaxis )
self . menuitem_showzeroline = qg . QAction (
self . menuitem_showzeroline = qw . QAction (
' Show Zero Lines ' , self . menu )
self . menuitem_showzeroline . setCheckable ( True )
self . menu . addAction ( self . menuitem_showzeroline )
self . menuitem_fixscalerange = qg . QAction (
self . menuitem_fixscalerange = qw . QAction (
' Fix Scale Ranges ' , self . menu )
self . menuitem_fixscalerange . setCheckable ( True )
self . menu . addAction ( self . menuitem_fixscalerange )
self . menuitem_allowdownsampling = qg . QAction (
self . menuitem_allowdownsampling = qw . QAction (
' Allow Downsampling ' , self . menu )
self . menuitem_allowdownsampling . setCheckable ( True )
self . menuitem_allowdownsampling . setChecked ( True )
self . menu . addAction ( self . menuitem_allowdownsampling )
self . menuitem_degap = qg . QAction ( ' Allow Degapping ' , self . menu )
self . menuitem_degap = qw . QAction ( ' Allow Degapping ' , self . menu )
self . menuitem_degap . setCheckable ( True )
self . menuitem_degap . setChecked ( True )
self . menu . addAction ( self . menuitem_degap )
self . menuitem_demean = qg . QAction ( ' Demean ' , self . menu )
self . menuitem_demean = qw . QAction ( ' Demean ' , self . menu )
self . menuitem_demean . setCheckable ( True )
self . menuitem_demean . setChecked ( True )
self . menu . addAction ( self . menuitem_demean )
self . menuitem_fft_filtering = qg . QAction (
self . menuitem_fft_filtering = qw . QAction (
' FFT Filtering ' , self . menu )
self . menuitem_fft_filtering . setCheckable ( True )
self . menuitem_fft_filtering . setChecked ( False )
self . menu . addAction ( self . menuitem_fft_filtering )
self . menuitem_lphp = qg . QAction (
self . menuitem_lphp = qw . QAction (
' Bandpass is Lowpass + Highpass ' , self . menu )
self . menuitem_lphp . setCheckable ( True )
self . menuitem_lphp . setChecked ( True )
self . menu . addAction ( self . menuitem_lphp )
self . menuitem_watch = qg . QAction ( ' Watch Files ' , self . menu )
self . menuitem_watch = qw . QAction ( ' Watch Files ' , self . menu )
self . menuitem_watch . setCheckable ( True )
self . menuitem_watch . setChecked ( False )
self . menu . addAction ( self . menuitem_watch )
self . visible_length_menu = qg . QMenu ( ' Visible Length ' , self . menu )
self . visible_length_menu = qw . QMenu ( ' Visible Length ' , self . menu )
menudef = [ ( x . key , x . value ) for x in
self . config . visible_length_setting ]
@ -999,70 +1008,58 @@ def MakePileViewerMainClass(base):
self . menu . addMenu ( self . visible_length_menu )
self . menu . addSeparator ( )
self . snufflings_menu = qg . QMenu ( ' Run Snuffling ' , self . menu )
self . snufflings_menu = qw . QMenu ( ' Run Snuffling ' , self . menu )
self . menu . addMenu ( self . snufflings_menu )
self . toggle_panel_menu = qg . QMenu ( ' Panels ' , self . menu )
self . toggle_panel_menu = qw . QMenu ( ' Panels ' , self . menu )
self . menu . addMenu ( self . toggle_panel_menu )
self . menuitem_reload = qg . QAction ( ' Reload Snufflings ' , self . menu )
self . menuitem_reload = qw . QAction ( ' Reload Snufflings ' , self . menu )
self . menu . addAction ( self . menuitem_reload )
self . connect (
self . menuitem_reload ,
qc . SIGNAL ( " triggered(bool) " ) ,
self . menuitem_reload . triggered . connect (
self . setup_snufflings )
self . menu . addSeparator ( )
self . menuitem_test = qg . QAction ( ' Test ' , self . menu )
self . menuitem_test . setCheckable ( True )
self . menuitem_test . setChecked ( False )
self . menu . addAction ( self . menuitem_test )
self . connect (
self . menuitem_test ,
qc . SIGNAL ( " toggled(bool) " ) ,
self . toggletest )
# Disable ShadowPileTest
if False :
self . menuitem_test = qw . QAction ( ' Test ' , self . menu )
self . menuitem_test . setCheckable ( True )
self . menuitem_test . setChecked ( False )
self . menu . addAction ( self . menuitem_test )
self . menuitem_test . triggered . connect (
self . toggletest )
self . menuitem_print = qg . QAction ( ' Print ' , self . menu )
self . menuitem_print = qw . QAction ( ' Print ' , self . menu )
self . menu . addAction ( self . menuitem_print )
self . connect (
self . menuitem_print ,
qc . SIGNAL ( " triggered(bool) " ) ,
self . menuitem_print . triggered . connect (
self . printit )
self . menuitem_svg = qg . QAction ( ' Save as SVG|PNG ' , self . menu )
self . menuitem_svg = qw . QAction ( ' Save as SVG|PNG ' , self . menu )
self . menu . addAction ( self . menuitem_svg )
self . connect (
self . menuitem_svg ,
qc . SIGNAL ( " triggered(bool) " ) ,
self . menuitem_svg . triggered . connect (
self . savesvg )
self . snuffling_help_menu = qg . QMenu ( ' Help ' , self . menu )
self . snuffling_help_menu = qw . QMenu ( ' Help ' , self . menu )
self . menu . addMenu ( self . snuffling_help_menu )
self . menuitem_help = qg . QAction (
self . menuitem_help = qw . QAction (
' Snuffler Controls ' , self . snuffling_help_menu )
self . snuffling_help_menu . addAction ( self . menuitem_help )
self . connect (
self . menuitem_help , qc . SIGNAL ( ' triggered(bool) ' ) , self . help )
self . menuitem_help . triggered . connect ( self . help )
self . snuffling_help_menu . addSeparator ( )
self . menuitem_about = qg . QAction ( ' About ' , self . menu )
self . menuitem_about = qw . QAction ( ' About ' , self . menu )
self . menu . addAction ( self . menuitem_about )
self . connect (
self . menuitem_about , qc . SIGNAL ( ' triggered(bool) ' ) , self . about )
self . menuitem_about . triggered . connect ( self . about )
self . menuitem_close = qg . QAction ( ' Close ' , self . menu )
self . menuitem_close = qw . QAction ( ' Close ' , self . menu )
self . menu . addAction ( self . menuitem_close )
self . connect (
self . menuitem_close ,
qc . SIGNAL ( " triggered(bool) " ) ,
self . myclose )
self . menuitem_close . triggered . connect ( self . myclose )
self . menu . addSeparator ( )
self . connect (
self . menu , qc . SIGNAL ( ' triggered(QAction*) ' ) , self . update )
self . menu . triggered . connect ( self . update )
self . time_projection = Projection ( )
self . set_time_range ( self . pile . get_tmin ( ) , self . pile . get_tmax ( ) )
@ -1082,7 +1079,7 @@ def MakePileViewerMainClass(base):
self . old_processed_traces = None
self . timer = qc . QTimer ( self )
self . connect ( self . timer , qc . SIGNAL ( " timeout() " ) , self . periodical )
self . timer . timeout . connect ( self . periodical )
self . timer . setInterval ( 1000 )
self . timer . start ( )
self . pile . add_listener ( self )
@ -1101,6 +1098,9 @@ def MakePileViewerMainClass(base):
self . timer_draw = Timer ( )
self . timer_cutout = Timer ( )
self . time_spent_painting = 0.0
self . time_last_painted = time . time ( )
self . timer_update_soon = None
self . interactive_range_change_time = 0.0
self . interactive_range_change_delay_time = 10.0
@ -1124,8 +1124,16 @@ def MakePileViewerMainClass(base):
self . closing = False
def update ( self ) :
self . timer_update_soon = None
qw . QWidget . update ( self )
def update_soon ( self ) :
if not self . timer_update_soon :
self . timer_update_soon = qc . QTimer . singleShot ( 50 , self . update )
def fail ( self , reason ) :
box = qg . QMessageBox ( self )
box = qw . QMessageBox ( self )
box . setText ( reason )
box . exec_ ( )
@ -1273,7 +1281,7 @@ def MakePileViewerMainClass(base):
if self . active_event_marker :
self . active_event_marker . set_active ( False )
self . emit ( qc . SIGNAL ( ' active_event_marker_changed(int) ' ) , - 1 )
self . active_event_marker_changed . emit ( - 1 )
def set_active_event_marker ( self , event_marker ) :
if self . active_event_marker :
@ -1285,7 +1293,7 @@ def MakePileViewerMainClass(base):
self . set_origin ( event )
i_active = self . markers . index ( self . active_event_marker )
self . emit ( qc . SIGNAL ( ' active_event_marker_changed(int) ' ) , i_active )
self . active_event_marker_changed . emit ( i_active )
def set_active_event ( self , event ) :
for marker in self . markers :
@ -1447,7 +1455,7 @@ def MakePileViewerMainClass(base):
def update_progress ( label , i , n ) :
abort = False
qg . qApp . processEvents ( )
qw . qApp . processEvents ( )
if n != 0 :
perc = i * 100 / n
else :
@ -1486,29 +1494,29 @@ def MakePileViewerMainClass(base):
self . _paths_to_load . extend ( paths )
qc . QTimer . singleShot ( 200 , self . load_queued )
def open_waveforms ( self , _ = None ) :
def open_waveforms ( self ) :
caption = ' Select one or more files to open '
fns = qg . QFileDialog . getOpenFileNames (
fns , _ = qw . QFileDialog . getOpenFileNames (
self , caption , options = qfiledialog_options )
self . load ( list ( str ( fn ) for fn in fns ) )
def open_waveform_directory ( self , _ = None ) :
if fns :
self . load ( list ( str ( fn ) for fn in fns ) )
def open_waveform_directory ( self ) :
caption = ' Select directory to scan for waveform files '
fn = qg . QFileDialog . getExistingDirectory (
dn = qw . QFileDialog . getExistingDirectory (
self , caption , options = qfiledialog_options )
self . load ( [ str ( fn ) ] )
if dn :
self . load ( [ str ( dn ) ] )
def open_stations ( self , fns = None ) :
caption = ' Select one or more files to open '
if not fns :
fns = qg . QFileDialog . getOpenFileNames (
fns , _ = qw . QFileDialog . getOpenFileNames (
self , caption , options = qfiledialog_options )
stations = [ pyrocko . model . load_stations ( str ( x ) ) for x in fns ]
@ -1540,7 +1548,7 @@ def MakePileViewerMainClass(base):
def pile_changed ( self , what ) :
self . pile_has_changed = True
self . emit ( qc . SIGNAL ( ' pile_has_changed_signal() ' ) )
self . pile_has_changed_signal . emit ( )
if self . automatic_updates :
self . update ( )
@ -1662,7 +1670,7 @@ def MakePileViewerMainClass(base):
def write_markers ( self , fn = None ) :
caption = " Choose a file name to write markers "
if not fn :
fn = qg . QFileDialog . getSaveFileName (
fn , _ = qw . QFileDialog . getSaveFileName (
self , caption , options = qfiledialog_options )
if fn :
Marker . save_markers (
@ -1672,7 +1680,7 @@ def MakePileViewerMainClass(base):
def write_selected_markers ( self , fn = None ) :
caption = " Choose a file name to write selected markers "
if not fn :
fn = qg . QFileDialog . getSaveFileName (
fn , _ = qw . QFileDialog . getSaveFileName (
self , caption , options = qfiledialog_options )
if fn :
Marker . save_markers (
@ -1687,7 +1695,7 @@ def MakePileViewerMainClass(base):
'''
caption = " Selet one or more files to open "
if not fn :
fn = qg . QFileDialog . getOpenFileName (
fn , _ = qw . QFileDialog . getOpenFileName (
self , caption , options = qfiledialog_options )
if fn :
self . add_events ( pyrocko . model . Event . load_catalog ( fn ) )
@ -1700,7 +1708,7 @@ def MakePileViewerMainClass(base):
'''
caption = " Selet one or more files to open "
if not fn :
fn = qg . QFileDialog . getOpenFileName (
fn , _ = qw . QFileDialog . getOpenFileName (
self , caption , options = qfiledialog_options )
if fn :
self . add_markers ( Marker . load_markers ( fn ) )
@ -1713,16 +1721,15 @@ def MakePileViewerMainClass(base):
def add_marker ( self , marker ) :
if marker not in self . markers :
self . markers . append ( marker )
self . emit (
qc . SIGNAL ( ' markers_added(int,int) ' ) ,
self . markers_added . emit (
len ( self . markers ) - 1 , len ( self . markers ) - 1 )
def add_markers ( self , markers ) :
len_before = len ( self . markers )
for m in markers :
self . markers . append ( m )
self . emit (
qc . SIGNAL ( ' markers_added(int,int) ' ) ,
if m not in self . markers :
self . markers . append ( m )
self . markers_added . emit (
len_before , len ( self . markers ) - 1 )
def remove_marker ( self , marker ) :
@ -1766,7 +1773,7 @@ def MakePileViewerMainClass(base):
pass
def remove_marker_from_menu ( self , istart , istop ) :
self . emit ( qc . SIGNAL ( ' markers_removed(int, int) ' ) , istart , istop )
self . markers_removed . emit ( istart , istop )
def set_markers ( self , markers ) :
self . markers = markers
@ -1811,6 +1818,10 @@ def MakePileViewerMainClass(base):
if self . picking :
self . stop_picking ( mouse_ev . x ( ) , mouse_ev . y ( ) )
self . emit_selected_markers ( )
if self . track_start :
self . update ( )
self . track_start = None
self . track_trange = None
self . update_status ( )
@ -1845,7 +1856,11 @@ def MakePileViewerMainClass(base):
tmin0 - dt - dtr * frac ,
tmax0 - dt + dtr * ( 1. - frac ) )
self . update ( )
if self . time_last_painted < time . time ( ) \
- self . time_spent_painting * 2. :
self . update ( )
else :
self . update_soon ( )
else :
self . hoovering ( point . x ( ) , point . y ( ) )
@ -2085,7 +2100,7 @@ def MakePileViewerMainClass(base):