Compare commits
30 Commits
5ef427ec12
...
feature/da
| Author | SHA1 | Date | |
|---|---|---|---|
| 65dbaad446 | |||
| 5b97d51517 | |||
| f03ace75e7 | |||
| 9c78471d20 | |||
| 09d2fb1022 | |||
| 3cae6d3a78 | |||
| 2e85d083a3 | |||
| ba4e6cfe50 | |||
| 1f16d01648 | |||
| 3069e7d526 | |||
| a9aeb7aaa3 | |||
| b9adb182ad | |||
| a823eb2440 | |||
| 486e3dc9c3 | |||
| 8d356050d7 | |||
| 43cab3767f | |||
| a1f6c5ffca | |||
| e4e7afa996 | |||
| 0634d24814 | |||
| 43c2b97b3d | |||
|
|
8d94440e77 | ||
|
|
66b7dea706 | ||
|
|
ebf6d4806a | ||
|
|
207d0b3a6f | ||
|
|
3b3bbc29d1 | ||
| 0c3fca9299 | |||
| 2d33a60421 | |||
|
|
a8c6f4c972 | ||
|
|
0d91f9e3fe | ||
|
|
494d281d61 |
191
PyLoT.py
191
PyLoT.py
@@ -60,7 +60,7 @@ except ImportError:
|
||||
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
|
||||
from matplotlib.figure import Figure
|
||||
|
||||
from pylot.core.analysis.magnitude import LocalMagnitude, MomentMagnitude
|
||||
from pylot.core.analysis.magnitude import LocalMagnitude, MomentMagnitude, calcsourcespec
|
||||
from pylot.core.io.data import Data
|
||||
from pylot.core.io.inputs import FilterOptions, PylotParameter
|
||||
from autoPyLoT import autoPyLoT
|
||||
@@ -76,14 +76,15 @@ from pylot.core.util.utils import fnConstructor, getLogin, \
|
||||
full_range, readFilterInformation, pick_color_plt, \
|
||||
pick_linestyle_plt, identifyPhaseID, excludeQualityClasses, \
|
||||
transform_colors_mpl, transform_colors_mpl_str, getAutoFilteroptions, check_all_obspy, \
|
||||
check_all_pylot, get_Bool, get_None
|
||||
check_all_pylot, get_bool, get_None
|
||||
from pylot.core.util.gui import make_pen
|
||||
from pylot.core.util.event import Event
|
||||
from pylot.core.io.location import create_creation_info, create_event
|
||||
from pylot.core.util.widgets import FilterOptionsDialog, NewEventDlg, \
|
||||
PylotCanvas, WaveformWidgetPG, PropertiesDlg, HelpForm, createAction, PickDlg, \
|
||||
ComparisonWidget, TuneAutopicker, PylotParaBox, AutoPickDlg, CanvasWidget, AutoPickWidget, \
|
||||
CompareEventsWidget, ProgressBarWidget, AddMetadataWidget, SingleTextLineDialog, LogWidget
|
||||
CompareEventsWidget, ProgressBarWidget, AddMetadataWidget, SingleTextLineDialog, LogWidget, PickQualitiesFromXml, \
|
||||
SourceSpecWindow, ChooseWaveFormWindow, SpectrogramTab
|
||||
from pylot.core.util.array_map import Array_map
|
||||
from pylot.core.util.structure import DATASTRUCTURE
|
||||
from pylot.core.util.thread import Thread, Worker
|
||||
@@ -116,17 +117,19 @@ class MainWindow(QMainWindow):
|
||||
if not infile:
|
||||
infile = os.path.join(os.path.expanduser('~'), '.pylot', 'pylot.in')
|
||||
print('Using default input file {}'.format(infile))
|
||||
if os.path.isfile(infile) == False:
|
||||
infile = QFileDialog().getOpenFileName(caption='Choose PyLoT-input file')
|
||||
if os.path.isfile(infile) is False:
|
||||
infile = QFileDialog().getOpenFileName(caption='Choose PyLoT-input file')[0]
|
||||
|
||||
if not os.path.exists(infile[0]):
|
||||
if not os.path.exists(infile):
|
||||
QMessageBox.warning(self, "PyLoT Warning",
|
||||
"No PyLoT-input file declared!")
|
||||
sys.exit(0)
|
||||
self.infile = infile[0]
|
||||
else:
|
||||
self.infile = infile
|
||||
"No PyLoT-input file declared! Using default parameters!")
|
||||
infile = None
|
||||
|
||||
self._inputs = PylotParameter(infile)
|
||||
if not infile:
|
||||
self._inputs.reset_defaults()
|
||||
|
||||
self.infile = infile
|
||||
self._props = None
|
||||
|
||||
self.gain = 1.
|
||||
@@ -178,6 +181,7 @@ class MainWindow(QMainWindow):
|
||||
self.autodata = Data(self)
|
||||
|
||||
self.fnames = None
|
||||
self.fnames_comp = None
|
||||
self._stime = None
|
||||
|
||||
# track deleted picks for logging
|
||||
@@ -480,7 +484,7 @@ class MainWindow(QMainWindow):
|
||||
"automatic pick "
|
||||
"data.", False)
|
||||
self.compare_action.setEnabled(False)
|
||||
self.qualities_action = self.createAction(parent=self, text='Show pick qualitites...',
|
||||
self.qualities_action = self.createAction(parent=self, text='Show pick qualities...',
|
||||
slot=self.pickQualities, shortcut='Alt+Q',
|
||||
icon=qualities_icon, tip='Histogram of pick qualities')
|
||||
self.qualities_action.setEnabled(False)
|
||||
@@ -493,7 +497,6 @@ class MainWindow(QMainWindow):
|
||||
icon=eventlist_xml_icon,
|
||||
tip='Create an Eventlist from a XML File')
|
||||
self.eventlist_xml_action.setEnabled(False)
|
||||
|
||||
printAction = self.createAction(self, "&Print event ...",
|
||||
self.show_event_information, QKeySequence.Print,
|
||||
print_icon,
|
||||
@@ -506,6 +509,8 @@ class MainWindow(QMainWindow):
|
||||
logAction = self.createAction(self, "&Show Log", self.showLogWidget,
|
||||
tip="""Display Log""")
|
||||
|
||||
logAction.setEnabled(use_logwidget)
|
||||
|
||||
# create button group for component selection
|
||||
|
||||
componentGroup = QActionGroup(self)
|
||||
@@ -695,14 +700,17 @@ class MainWindow(QMainWindow):
|
||||
wf_tab = QtWidgets.QWidget(self)
|
||||
array_tab = QtWidgets.QWidget(self)
|
||||
events_tab = QtWidgets.QWidget(self)
|
||||
spectro_tab = QtWidgets.QWidget(self)
|
||||
|
||||
# init main widgets layouts
|
||||
self.wf_layout = QtWidgets.QVBoxLayout()
|
||||
self.array_layout = QtWidgets.QVBoxLayout()
|
||||
self.events_layout = QtWidgets.QVBoxLayout()
|
||||
self.spectro_layout = QtWidgets.QVBoxLayout()
|
||||
wf_tab.setLayout(self.wf_layout)
|
||||
array_tab.setLayout(self.array_layout)
|
||||
events_tab.setLayout(self.events_layout)
|
||||
spectro_tab.setLayout(self.spectro_layout)
|
||||
|
||||
# tighten up layouts inside tabs
|
||||
for layout in [self.wf_layout, self.array_layout, self.events_layout]:
|
||||
@@ -713,12 +721,14 @@ class MainWindow(QMainWindow):
|
||||
self.tabs.addTab(wf_tab, 'Waveform Plot')
|
||||
self.tabs.addTab(array_tab, 'Array Map')
|
||||
self.tabs.addTab(events_tab, 'Eventlist')
|
||||
self.tabs.addTab(spectro_tab, 'Spectro')
|
||||
|
||||
self.wf_layout.addWidget(self.no_data_label)
|
||||
self.wf_layout.addWidget(self.wf_scroll_area)
|
||||
self.wf_scroll_area.setWidgetResizable(True)
|
||||
self.init_array_tab()
|
||||
self.init_event_table()
|
||||
self.init_spectro_tab()
|
||||
self.tabs.setCurrentIndex(0)
|
||||
|
||||
self.eventLabel = QLabel()
|
||||
@@ -731,15 +741,19 @@ class MainWindow(QMainWindow):
|
||||
_widget.setLayout(self._main_layout)
|
||||
_widget.showFullScreen()
|
||||
|
||||
|
||||
if use_logwidget:
|
||||
self.logwidget = LogWidget(parent=None)
|
||||
self.logwidget.show()
|
||||
|
||||
sys.stdout = self.logwidget.stdout
|
||||
sys.stderr = self.logwidget.stderr
|
||||
self.stdout = self.logwidget.stdout
|
||||
self.stderr = self.logwidget.stderr
|
||||
|
||||
self.setCentralWidget(_widget)
|
||||
|
||||
# Need to store PickQualities Window somewhere so it doesnt disappear
|
||||
self.pickQualitiesWindow = None
|
||||
|
||||
|
||||
def init_wfWidget(self):
|
||||
xlab = self.startTime.strftime('seconds since %Y/%m/%d %H:%M:%S (%Z)')
|
||||
plottitle = None # "Overview: {0} components ".format(self.getComponent())
|
||||
@@ -1117,16 +1131,19 @@ class MainWindow(QMainWindow):
|
||||
else:
|
||||
return
|
||||
|
||||
def getWFFnames_from_eventbox(self, eventbox=None):
|
||||
def getWFFnames_from_eventbox(self, eventbox: str = None, subpath: str = None) -> list:
|
||||
'''
|
||||
Return waveform filenames from event in eventbox.
|
||||
'''
|
||||
# TODO: add dataStructure class for obspyDMT here, this is just a workaround!
|
||||
eventpath = self.get_current_event_path(eventbox)
|
||||
basepath = eventpath.split(os.path.basename(eventpath))[0]
|
||||
if subpath:
|
||||
eventpath = os.path.join(eventpath, subpath)
|
||||
if not os.path.isdir(eventpath):
|
||||
return []
|
||||
if self.dataStructure:
|
||||
if not eventpath:
|
||||
return
|
||||
return []
|
||||
fnames = [os.path.join(eventpath, f) for f in os.listdir(eventpath)]
|
||||
else:
|
||||
raise DatastructureError('not specified')
|
||||
@@ -1170,7 +1187,7 @@ class MainWindow(QMainWindow):
|
||||
'''
|
||||
if not self.project:
|
||||
self.createNewProject()
|
||||
ed = getExistingDirectories(self, 'Select event directories...')
|
||||
ed = GetExistingDirectories(self, 'Select event directories...')
|
||||
if ed.exec_():
|
||||
eventlist = [event for event in ed.selectedFiles() if not event.endswith('EVENTS-INFO')]
|
||||
basepath = eventlist[0].split(os.path.basename(eventlist[0]))[0]
|
||||
@@ -1371,7 +1388,7 @@ class MainWindow(QMainWindow):
|
||||
index = eventBox.currentIndex()
|
||||
tv = QtWidgets.QTableView()
|
||||
header = tv.horizontalHeader()
|
||||
header.setResizeMode(QtWidgets.QHeaderView.ResizeToContents)
|
||||
header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
|
||||
header.setStretchLastSection(True)
|
||||
header.hide()
|
||||
tv.verticalHeader().hide()
|
||||
@@ -1668,15 +1685,54 @@ class MainWindow(QMainWindow):
|
||||
|
||||
def pickQualities(self):
|
||||
path = self.get_current_event_path()
|
||||
getQualitiesfromxml(path, self._inputs.get('timeerrorsP'), self._inputs.get('timeerrorsS'), plotflag=1)
|
||||
return
|
||||
(_, plot) = getQualitiesfromxml(path, self._inputs.get('timeerrorsP'), self._inputs.get('timeerrorsS'),plotflag=1)
|
||||
self.pickQualitiesWindow = PickQualitiesFromXml(figure=plot, path=self.get_current_event_path(),inputVar=self._inputs)
|
||||
self.pickQualitiesWindow.showUI()
|
||||
return
|
||||
|
||||
# WIP JG
|
||||
def eventlistXml(self):
|
||||
path = self._inputs['rootpath'] + '/' + self._inputs['datapath'] + '/' + self._inputs['database']
|
||||
outpath = self.project.location[:self.project.location.rfind('/')]
|
||||
geteventlistfromxml(path, outpath)
|
||||
return
|
||||
|
||||
# WIP JG
|
||||
def spectogramView(self):
|
||||
global test
|
||||
stations = []
|
||||
names = []
|
||||
traces = {}
|
||||
for tr in self.get_data().wfdata.traces:
|
||||
if not tr.stats.station in stations:
|
||||
stations.append(tr.stats.station)
|
||||
names.append(tr.stats.network + '.' + tr.stats.station)
|
||||
for station in stations:
|
||||
traces[station] = {}
|
||||
for ch in ['Z', 'N', 'E']:
|
||||
for tr in self.get_data().wfdata.select(component=ch).traces:
|
||||
traces[tr.stats.station][ch] = tr
|
||||
|
||||
names.sort()
|
||||
a = self.get_current_event()
|
||||
|
||||
print (self.get_data().wfdata.traces[0])
|
||||
|
||||
test = SpectrogramTab(traces, self.get_data().wfdata)
|
||||
height = self.tabs.widget(0).height()
|
||||
width = self.tabs.widget(0).width()
|
||||
self.tabs.setCurrentIndex(3)
|
||||
figCanvas = test.makeSpecFig(direction=self.dispComponent, height = height, width = width, parent = self.tabs.widget)
|
||||
return figCanvas
|
||||
#self.spectro_layout.addWidget()
|
||||
# self.get_data().wfdata.spectrogram()
|
||||
# self.tabs.addTab(figCanvas, 'Spectrogram')
|
||||
# self.tabs[3] = figCanvas
|
||||
# self.refreshTabs()
|
||||
# test.show()
|
||||
|
||||
|
||||
|
||||
def compareMulti(self):
|
||||
if not self.compareoptions:
|
||||
return
|
||||
@@ -1862,6 +1918,13 @@ class MainWindow(QMainWindow):
|
||||
self.newWF(plot=False)
|
||||
self.update_obspy_dmt()
|
||||
self.refresh_array_map()
|
||||
if self.tabs.currentIndex() == 3:
|
||||
if self.spectroWidget != None:
|
||||
self.spectro_layout.removeWidget(self.spectroWidget)
|
||||
newSpectroWidget = self.spectogramView()
|
||||
self.spectro_layout.addWidget(newSpectroWidget)
|
||||
self.spectroWidget = newSpectroWidget
|
||||
|
||||
|
||||
def newWF(self, event=None, plot=True):
|
||||
'''
|
||||
@@ -1892,13 +1955,20 @@ class MainWindow(QMainWindow):
|
||||
|
||||
def prepareLoadWaveformData(self):
|
||||
self.fnames = self.getWFFnames_from_eventbox()
|
||||
self.fnames_syn = []
|
||||
self.fnames_comp = []
|
||||
fnames_comp = self.getWFFnames_from_eventbox(subpath='compare')
|
||||
self.dataPlot.activateCompareOptions(bool(fnames_comp))
|
||||
if fnames_comp:
|
||||
if self.dataPlot.comp_checkbox.isChecked():
|
||||
self.fnames_comp = fnames_comp
|
||||
|
||||
eventpath = self.get_current_event_path()
|
||||
basepath = eventpath.split(os.path.basename(eventpath))[0]
|
||||
self.obspy_dmt = check_obspydmt_structure(basepath)
|
||||
self.dataPlot.activateObspyDMToptions(self.obspy_dmt)
|
||||
if self.obspy_dmt:
|
||||
self.prepareObspyDMT_data(eventpath)
|
||||
self.dataPlot.activateCompareOptions(True)
|
||||
|
||||
def loadWaveformData(self):
|
||||
'''
|
||||
@@ -1929,7 +1999,7 @@ class MainWindow(QMainWindow):
|
||||
tstop = None
|
||||
|
||||
self.data.setWFData(self.fnames,
|
||||
self.fnames_syn,
|
||||
self.fnames_comp,
|
||||
checkRotated=True,
|
||||
metadata=self.metadata,
|
||||
tstart=tstart,
|
||||
@@ -1937,7 +2007,7 @@ class MainWindow(QMainWindow):
|
||||
|
||||
def prepareObspyDMT_data(self, eventpath):
|
||||
qcbox_processed = self.dataPlot.qcombo_processed
|
||||
qcheckb_syn = self.dataPlot.syn_checkbox
|
||||
qcheckb_syn = self.dataPlot.comp_checkbox
|
||||
qcbox_processed.setEnabled(False)
|
||||
qcheckb_syn.setEnabled(False)
|
||||
for fpath in os.listdir(eventpath):
|
||||
@@ -1945,8 +2015,8 @@ class MainWindow(QMainWindow):
|
||||
if 'syngine' in fpath:
|
||||
eventpath_syn = os.path.join(eventpath, fpath)
|
||||
qcheckb_syn.setEnabled(True)
|
||||
if self.dataPlot.syn_checkbox.isChecked():
|
||||
self.fnames_syn = [os.path.join(eventpath_syn, filename) for filename in os.listdir(eventpath_syn)]
|
||||
if self.dataPlot.comp_checkbox.isChecked():
|
||||
self.fnames_comp = [os.path.join(eventpath_syn, filename) for filename in os.listdir(eventpath_syn)]
|
||||
if 'processed' in fpath:
|
||||
qcbox_processed.setEnabled(True)
|
||||
if qcbox_processed.isEnabled():
|
||||
@@ -2119,6 +2189,7 @@ class MainWindow(QMainWindow):
|
||||
self.locateEventAction.setEnabled(True)
|
||||
self.qualities_action.setEnabled(True)
|
||||
self.eventlist_xml_action.setEnabled(True)
|
||||
|
||||
if True in self.comparable.values():
|
||||
self.compare_action.setEnabled(True)
|
||||
self.draw()
|
||||
@@ -2226,7 +2297,7 @@ class MainWindow(QMainWindow):
|
||||
comp = self.getComponent()
|
||||
title = 'section: {0} components'.format(zne_text[comp])
|
||||
wfst = self.get_data().getWFData()
|
||||
wfsyn = self.get_data().getSynWFData()
|
||||
wfsyn = self.get_data().getAltWFdata()
|
||||
if self.filterActionP.isChecked() and filter:
|
||||
self.filterWaveformData(plot=False, phase='P')
|
||||
elif self.filterActionS.isChecked() and filter:
|
||||
@@ -2235,7 +2306,7 @@ class MainWindow(QMainWindow):
|
||||
# wfst += self.get_data().getWFData().select(component=alter_comp)
|
||||
plotWidget = self.getPlotWidget()
|
||||
self.adjustPlotHeight()
|
||||
if get_Bool(settings.value('large_dataset')) == True:
|
||||
if get_bool(settings.value('large_dataset')):
|
||||
self.plot_method = 'fast'
|
||||
else:
|
||||
self.plot_method = 'normal'
|
||||
@@ -2538,18 +2609,21 @@ class MainWindow(QMainWindow):
|
||||
print("Warning! No network, station, and location info available!")
|
||||
return
|
||||
self.update_status('picking on station {0}'.format(station))
|
||||
data = self.get_data().getOriginalWFData().copy()
|
||||
wfdata = self.get_data().getOriginalWFData().copy()
|
||||
wfdata_comp = self.get_data().getAltWFdata().copy()
|
||||
event = self.get_current_event()
|
||||
wftype = self.dataPlot.qcombo_processed.currentText() if self.obspy_dmt else None
|
||||
pickDlg = PickDlg(self, parameter=self._inputs,
|
||||
data=data.select(station=station),
|
||||
data=wfdata.select(station=station),
|
||||
data_compare=wfdata_comp.select(station=station),
|
||||
station=station, network=network,
|
||||
location=location,
|
||||
picks=self.getPicksOnStation(station, 'manual'),
|
||||
autopicks=self.getPicksOnStation(station, 'auto'),
|
||||
metadata=self.metadata, event=event,
|
||||
model=self.inputs.get('taup_model'),
|
||||
filteroptions=self.filteroptions, wftype=wftype)
|
||||
filteroptions=self.filteroptions, wftype=wftype,
|
||||
show_comp_data=self.dataPlot.comp_checkbox.isChecked())
|
||||
if self.filterActionP.isChecked():
|
||||
pickDlg.currentPhase = "P"
|
||||
pickDlg.filterWFData()
|
||||
@@ -2861,7 +2935,9 @@ class MainWindow(QMainWindow):
|
||||
self.log_deleted_picks([deleted_pick])
|
||||
|
||||
def log_deleted_picks(self, deleted_picks, event_path=None):
|
||||
''' Log deleted picks to list self.deleted_picks '''
|
||||
'''
|
||||
Log deleted picks to list self.deleted_picks
|
||||
'''
|
||||
if not event_path:
|
||||
event_path = self.get_current_event_path()
|
||||
for deleted_pick in deleted_picks:
|
||||
@@ -2875,7 +2951,9 @@ class MainWindow(QMainWindow):
|
||||
self.deleted_picks[event_path].append(deleted_pick)
|
||||
|
||||
def dump_deleted_picks(self, event_path):
|
||||
''' Save deleted picks to json file for event in event_path. Load old file before and merge'''
|
||||
'''
|
||||
Save deleted picks to json file for event in event_path. Load old file before and merge
|
||||
'''
|
||||
try:
|
||||
deleted_picks_from_file = self.load_deleted_picks(event_path)
|
||||
except Exception as e:
|
||||
@@ -3071,11 +3149,13 @@ class MainWindow(QMainWindow):
|
||||
lt = locateTool[loctool]
|
||||
# get working directory
|
||||
locroot = parameter['nllocroot']
|
||||
#locroot = 'E:/NLL/src/Insheim'
|
||||
if locroot is None:
|
||||
self.PyLoTprefs()
|
||||
self.locate_event()
|
||||
|
||||
ctrfile = os.path.join(locroot, 'run', parameter['ctrfile'])
|
||||
#ctrfile = 'E:/NLL/src/Insheim/run/Insheim_min1d032016.in'
|
||||
ttt = parameter['ttpatter']
|
||||
outfile = parameter['outpatter']
|
||||
eventname = self.get_current_event_name()
|
||||
@@ -3086,7 +3166,7 @@ class MainWindow(QMainWindow):
|
||||
phasefile = os.path.join(obsdir, filename + '.obs')
|
||||
lt.modify_inputs(ctrfile, locroot, filename, phasefile, ttt)
|
||||
try:
|
||||
lt.locate(ctrfile)
|
||||
lt.locate(ctrfile, self._inputs)
|
||||
except RuntimeError as e:
|
||||
print(e.message)
|
||||
# finally:
|
||||
@@ -3140,7 +3220,7 @@ class MainWindow(QMainWindow):
|
||||
'''
|
||||
if checked: pass # dummy argument for QAction trigger signal
|
||||
self.tabs.setCurrentIndex(1)
|
||||
# if there is no metadata (invetories is an empty list), just initialize the default empty tab
|
||||
# if there is no metadata (inventories is an empty list), just initialize the default empty tab
|
||||
if not self.metadata.inventories:
|
||||
self.init_array_tab()
|
||||
return
|
||||
@@ -3162,6 +3242,15 @@ class MainWindow(QMainWindow):
|
||||
self.tabs.setCurrentIndex(index)
|
||||
self.refresh_array_map()
|
||||
|
||||
def init_spectro_tab(self):
|
||||
'''
|
||||
Init spectrogram tab with currently selected event.
|
||||
'''
|
||||
self.spectroWidget = None
|
||||
#self.spectro_layout.addWidget( self.spectogramView() )
|
||||
pass
|
||||
|
||||
|
||||
def array_map_thread(self):
|
||||
'''
|
||||
Start modal thread to init the array_map object.
|
||||
@@ -3384,7 +3473,7 @@ class MainWindow(QMainWindow):
|
||||
self.event_table.setCellWidget(r_index, c_index, item)
|
||||
|
||||
header = self.event_table.horizontalHeader()
|
||||
header.setResizeMode(QtWidgets.QHeaderView.ResizeToContents)
|
||||
header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
|
||||
header.setStretchLastSection(True)
|
||||
self.event_table.cellChanged[int, int].connect(cell_changed)
|
||||
self.event_table.cellClicked[int, int].connect(cell_clicked)
|
||||
@@ -3491,7 +3580,7 @@ class MainWindow(QMainWindow):
|
||||
|
||||
wf_select = Stream()
|
||||
# restitute only picked traces
|
||||
for station in np.unique(self.getPicks('manual').keys() + self.getPicks('auto').keys()):
|
||||
for station in np.unique(list(self.getPicks('manual').keys()) + list(self.getPicks('auto').keys())):
|
||||
wf_select += wf_copy.select(station=station)
|
||||
|
||||
corr_wf = restitute_data(wf_select, self.metadata)
|
||||
@@ -3670,7 +3759,7 @@ class MainWindow(QMainWindow):
|
||||
filename = fnm[0] + '.plp'
|
||||
self.project.parameter = self._inputs
|
||||
settings = QSettings()
|
||||
autosaveXML = get_Bool(settings.value('autosaveXML', True))
|
||||
autosaveXML = get_bool(settings.value('autosaveXML', True))
|
||||
if autosaveXML:
|
||||
self.exportEvents()
|
||||
if not self.project.save(filename): return False
|
||||
@@ -3694,7 +3783,7 @@ class MainWindow(QMainWindow):
|
||||
self.metadata.clear_inventory()
|
||||
self.project.parameter = self._inputs
|
||||
settings = QSettings()
|
||||
autosaveXML = get_Bool(settings.value('autosaveXML', True))
|
||||
autosaveXML = get_bool(settings.value('autosaveXML', True))
|
||||
if autosaveXML:
|
||||
self.exportEvents()
|
||||
if not self.project.save(): return False
|
||||
@@ -3783,7 +3872,7 @@ class MainWindow(QMainWindow):
|
||||
def helpHelp(self):
|
||||
if checkurl():
|
||||
form = HelpForm(self,
|
||||
'https://ariadne.geophysik.ruhr-uni-bochum.de/trac/PyLoT/wiki')
|
||||
'https://github.com/seismology-RUB/PyLoT')
|
||||
else:
|
||||
form = HelpForm(self, ':/help.html')
|
||||
form.show()
|
||||
@@ -3963,13 +4052,13 @@ class Project(object):
|
||||
return project
|
||||
|
||||
|
||||
class getExistingDirectories(QFileDialog):
|
||||
class GetExistingDirectories(QFileDialog):
|
||||
'''
|
||||
File dialog with possibility to select multiple folders.
|
||||
'''
|
||||
|
||||
def __init__(self, *args):
|
||||
super(getExistingDirectories, self).__init__(*args)
|
||||
super(GetExistingDirectories, self).__init__(*args)
|
||||
self.setOption(self.DontUseNativeDialog, True)
|
||||
self.setOption(self.ReadOnly, True)
|
||||
self.setFileMode(self.Directory)
|
||||
@@ -3995,16 +4084,7 @@ def create_window():
|
||||
return app, app_created
|
||||
|
||||
|
||||
def main(args=None):
|
||||
project_filename = None
|
||||
# args.project_filename = 'C:/Shared/AlpArray/alparray_data/project_alparray_test.plp'
|
||||
pylot_infile = None
|
||||
if args:
|
||||
if args.project_filename:
|
||||
project_filename = args.project_filename
|
||||
if args.input_filename:
|
||||
pylot_infile = args.input_filename
|
||||
reset_qsettings = args.reset_qsettings
|
||||
def main(project_filename=None, pylot_infile=None, reset_qsettings=False):
|
||||
|
||||
# create the Qt application
|
||||
pylot_app, app_created = create_window()
|
||||
@@ -4053,4 +4133,5 @@ if __name__ == "__main__":
|
||||
parser.add_argument('--reset_qsettings', default=False, action='store_true',
|
||||
help='reset qsettings (debug option)')
|
||||
args = parser.parse_args()
|
||||
sys.exit(main(args))
|
||||
sys.exit(main(project_filename=args.project_filename, pylot_infile=args.input_filename,
|
||||
reset_qsettings=args.reset_qsettings))
|
||||
|
||||
@@ -99,7 +99,7 @@ We hope to solve these with the next release.
|
||||
|
||||
## Staff
|
||||
|
||||
Original author(s): L. Kueperkoch, S. Wehling-Benatelli, M. Bischoff (PILOT)
|
||||
Original author(s): M. Rische, S. Wehling-Benatelli, L. Kueperkoch, M. Bischoff (PILOT)
|
||||
|
||||
Developer(s): S. Wehling-Benatelli, M. Paffrath, L. Kueperkoch, K. Olbert, M. Bischoff, C. Wollin, M. Rische, D. Arnold, K. Cökerim, S. Zimmermann
|
||||
|
||||
|
||||
@@ -7,4 +7,6 @@
|
||||
#$ -l h_vmem=2G
|
||||
#$ -l os=*stretch
|
||||
|
||||
python ./autoPyLoT.py -i /home/marcel/.pylot/pylot_alparray_mantle_corr_stack_0.03-0.5.in -dmt processed -c $NSLOTS
|
||||
conda activate pylot_38
|
||||
|
||||
python ./autoPyLoT.py -i /home/marcel/.pylot/pylot_janis_noisy.in -c $NSLOTS
|
||||
|
||||
BIN
icons/eventlist_xml_button.png
Normal file
BIN
icons/eventlist_xml_button.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
BIN
icons/pick_qualities_button.png
Normal file
BIN
icons/pick_qualities_button.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
218853
icons_rc_3.py
218853
icons_rc_3.py
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ dependencies:
|
||||
- numpy=1.22.3
|
||||
- obspy=1.3.0
|
||||
- pyqtgraph=0.12.4
|
||||
- pyside2=5.13.2
|
||||
- pyside2>=5.13.2
|
||||
- python=3.8.12
|
||||
- qt=5.12.9
|
||||
- qt>=5.12.9
|
||||
- scipy=1.8.0
|
||||
@@ -144,6 +144,10 @@ class Magnitude(object):
|
||||
azimuthal_gap=self.origin_id.get_referred_object().quality.azimuthal_gap)
|
||||
else:
|
||||
# no scaling necessary
|
||||
# Temporary fix needs rework
|
||||
if (len(self.magnitudes.keys()) == 0):
|
||||
print("Error in local magnitude calculation ")
|
||||
return None
|
||||
mag = ope.Magnitude(
|
||||
mag=np.median([M.mag for M in self.magnitudes.values()]),
|
||||
magnitude_type=self.type,
|
||||
@@ -414,6 +418,10 @@ class MomentMagnitude(Magnitude):
|
||||
distance = degrees2kilometers(a.distance)
|
||||
azimuth = a.azimuth
|
||||
incidence = a.takeoff_angle
|
||||
if not 0. <= incidence <= 360.:
|
||||
if self.verbose:
|
||||
print(f'WARNING: Incidence angle outside bounds - {incidence}')
|
||||
return
|
||||
w0, fc = calcsourcespec(scopy, onset, self.p_velocity, distance,
|
||||
azimuth, incidence, self.p_attenuation,
|
||||
self.plot_flag, self.verbose)
|
||||
@@ -432,6 +440,40 @@ class MomentMagnitude(Magnitude):
|
||||
self.event.station_magnitudes.append(magnitude)
|
||||
self.magnitudes = (station, magnitude)
|
||||
|
||||
# WIP JG
|
||||
def getSourceSpec(self):
|
||||
for a in self.arrivals:
|
||||
if a.phase not in 'pP':
|
||||
continue
|
||||
# make sure calculating Mo only from reliable onsets
|
||||
# NLLoc: time_weight = 0 => do not use onset!
|
||||
if a.time_weight == 0:
|
||||
continue
|
||||
pick = a.pick_id.get_referred_object()
|
||||
station = pick.waveform_id.station_code
|
||||
if len(self.stream) <= 2:
|
||||
print("Station:" '{0}'.format(station))
|
||||
print("WARNING: No instrument corrected data available,"
|
||||
" no magnitude calculation possible! Go on.")
|
||||
continue
|
||||
wf = self.stream.select(station=station)
|
||||
if not wf:
|
||||
continue
|
||||
try:
|
||||
scopy = wf.copy()
|
||||
except AssertionError:
|
||||
print("WARNING: Something's wrong with the data,"
|
||||
"station {},"
|
||||
"no calculation of moment magnitude possible! Go on.".format(station))
|
||||
continue
|
||||
onset = pick.time
|
||||
distance = degrees2kilometers(a.distance)
|
||||
azimuth = a.azimuth
|
||||
incidence = a.takeoff_angle
|
||||
w0, fc, plt = calcsourcespec(scopy, onset, self.p_velocity, distance,
|
||||
azimuth, incidence, self.p_attenuation,
|
||||
3, self.verbose)
|
||||
return w0, fc, plt
|
||||
|
||||
def calcMoMw(wfstream, w0, rho, vp, delta, verbosity=False):
|
||||
'''
|
||||
@@ -602,7 +644,7 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
|
||||
N = min(int(np.power(m, 2)), 16384)
|
||||
# N = int(np.power(m, 2))
|
||||
y = dt * np.fft.fft(xdat, N)
|
||||
Y = abs(y[: N / 2])
|
||||
Y = abs(y[: int(N / 2)])
|
||||
L = (N - 1) / freq
|
||||
f = np.arange(0, fny, 1 / L)
|
||||
|
||||
@@ -679,6 +721,8 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
|
||||
plt.xlabel('Frequency [Hz]')
|
||||
plt.ylabel('Amplitude [m/Hz]')
|
||||
plt.grid()
|
||||
if iplot == 3:
|
||||
return w0, Fc, plt
|
||||
plt.show()
|
||||
try:
|
||||
input()
|
||||
|
||||
@@ -260,7 +260,6 @@ class Data(object):
|
||||
can be a str or a list of strings of ['manual', 'auto', 'origin', 'magnitude']
|
||||
"""
|
||||
from pylot.core.util.defaults import OUTPUTFORMATS
|
||||
|
||||
if not type(fcheck) == list:
|
||||
fcheck = [fcheck]
|
||||
|
||||
@@ -321,35 +320,61 @@ class Data(object):
|
||||
if lendiff != 0:
|
||||
print("Manual as well as automatic picks available. Prefered the {} manual ones!".format(lendiff))
|
||||
|
||||
|
||||
no_uncertainties_p = []
|
||||
no_uncertainties_s = []
|
||||
if upperErrors:
|
||||
# check for pick uncertainties exceeding adjusted upper errors
|
||||
# Picks with larger uncertainties will not be saved in output file!
|
||||
for j in range(len(picks)):
|
||||
for i in range(len(picks_copy)):
|
||||
if picks_copy[i].phase_hint[0] == 'P':
|
||||
if (picks_copy[i].time_errors['upper_uncertainty'] >= upperErrors[0]) or \
|
||||
(picks_copy[i].time_errors['uncertainty'] is None):
|
||||
# Skipping pick if no upper_uncertainty is found and warning user
|
||||
if picks_copy[i].time_errors['upper_uncertainty'] is None:
|
||||
#print("{1} P-Pick of station {0} does not have upper_uncertainty and cant be checked".format(
|
||||
# picks_copy[i].waveform_id.station_code,
|
||||
# picks_copy[i].method_id))
|
||||
if not picks_copy[i].waveform_id.station_code in no_uncertainties_p:
|
||||
no_uncertainties_p.append(picks_copy[i].waveform_id.station_code)
|
||||
continue
|
||||
|
||||
#print ("checking for upper_uncertainty")
|
||||
if (picks_copy[i].time_errors['uncertainty'] is None) or \
|
||||
(picks_copy[i].time_errors['upper_uncertainty'] >= upperErrors[0]):
|
||||
print("Uncertainty exceeds or equal adjusted upper time error!")
|
||||
print("Adjusted uncertainty: {}".format(upperErrors[0]))
|
||||
print("Pick uncertainty: {}".format(picks_copy[i].time_errors['uncertainty']))
|
||||
print("{1} P-Pick of station {0} will not be saved in outputfile".format(
|
||||
picks_copy[i].waveform_id.station_code,
|
||||
picks_copy[i].method_id))
|
||||
print("#")
|
||||
del picks_copy[i]
|
||||
break
|
||||
if picks_copy[i].phase_hint[0] == 'S':
|
||||
if (picks_copy[i].time_errors['upper_uncertainty'] >= upperErrors[1]) or \
|
||||
(picks_copy[i].time_errors['uncertainty'] is None):
|
||||
|
||||
# Skipping pick if no upper_uncertainty is found and warning user
|
||||
if picks_copy[i].time_errors['upper_uncertainty'] is None:
|
||||
#print("{1} S-Pick of station {0} does not have upper_uncertainty and cant be checked".format(
|
||||
#picks_copy[i].waveform_id.station_code,
|
||||
#picks_copy[i].method_id))
|
||||
if not picks_copy[i].waveform_id.station_code in no_uncertainties_s:
|
||||
no_uncertainties_s.append(picks_copy[i].waveform_id.station_code)
|
||||
continue
|
||||
|
||||
|
||||
if (picks_copy[i].time_errors['uncertainty'] is None) or \
|
||||
(picks_copy[i].time_errors['upper_uncertainty'] >= upperErrors[1]):
|
||||
print("Uncertainty exceeds or equal adjusted upper time error!")
|
||||
print("Adjusted uncertainty: {}".format(upperErrors[1]))
|
||||
print("Pick uncertainty: {}".format(picks_copy[i].time_errors['uncertainty']))
|
||||
print("{1} S-Pick of station {0} will not be saved in outputfile".format(
|
||||
picks_copy[i].waveform_id.station_code,
|
||||
picks_copy[i].method_id))
|
||||
print("#")
|
||||
del picks_copy[i]
|
||||
break
|
||||
for s in no_uncertainties_p:
|
||||
print("P-Pick of station {0} does not have upper_uncertainty and cant be checked".format(s))
|
||||
for s in no_uncertainties_s:
|
||||
print("S-Pick of station {0} does not have upper_uncertainty and cant be checked".format(s))
|
||||
|
||||
if fnext == '.obs':
|
||||
try:
|
||||
@@ -426,20 +451,25 @@ class Data(object):
|
||||
data.filter(**kwargs)
|
||||
self.dirty = True
|
||||
|
||||
def setWFData(self, fnames, fnames_syn=None, checkRotated=False, metadata=None, tstart=0, tstop=0):
|
||||
def setWFData(self, fnames, fnames_alt=None, checkRotated=False, metadata=None, tstart=0, tstop=0):
|
||||
"""
|
||||
Clear current waveform data and set given waveform data
|
||||
:param fnames: waveform data names to append
|
||||
:param fnames_alt: alternative data to show (e.g. synthetic/processed)
|
||||
:type fnames: list
|
||||
"""
|
||||
self.wfdata = Stream()
|
||||
self.wforiginal = None
|
||||
self.wfsyn = Stream()
|
||||
self.wf_alt = Stream()
|
||||
if tstart == tstop:
|
||||
tstart = tstop = None
|
||||
self.tstart = tstart
|
||||
self.tstop = tstop
|
||||
|
||||
# remove directories
|
||||
fnames = [fname for fname in fnames if not os.path.isdir(fname)]
|
||||
fnames_alt = [fname for fname in fnames_alt if not os.path.isdir(fname)]
|
||||
|
||||
# if obspy_dmt:
|
||||
# wfdir = 'raw'
|
||||
# self.processed = False
|
||||
@@ -457,8 +487,8 @@ class Data(object):
|
||||
# wffnames = fnames
|
||||
if fnames is not None:
|
||||
self.appendWFData(fnames)
|
||||
if fnames_syn is not None:
|
||||
self.appendWFData(fnames_syn, synthetic=True)
|
||||
if fnames_alt is not None:
|
||||
self.appendWFData(fnames_alt, alternative=True)
|
||||
else:
|
||||
return False
|
||||
|
||||
@@ -478,7 +508,7 @@ class Data(object):
|
||||
self.dirty = False
|
||||
return True
|
||||
|
||||
def appendWFData(self, fnames, synthetic=False):
|
||||
def appendWFData(self, fnames, alternative=False):
|
||||
"""
|
||||
Read waveform data from fnames and append it to current wf data
|
||||
:param fnames: waveform data to append
|
||||
@@ -491,20 +521,20 @@ class Data(object):
|
||||
if self.dirty:
|
||||
self.resetWFData()
|
||||
|
||||
real_or_syn_data = {True: self.wfsyn,
|
||||
False: self.wfdata}
|
||||
orig_or_alternative_data = {True: self.wf_alt,
|
||||
False: self.wfdata}
|
||||
|
||||
warnmsg = ''
|
||||
for fname in set(fnames):
|
||||
try:
|
||||
real_or_syn_data[synthetic] += read(fname, starttime=self.tstart, endtime=self.tstop)
|
||||
orig_or_alternative_data[alternative] += read(fname, starttime=self.tstart, endtime=self.tstop)
|
||||
except TypeError:
|
||||
try:
|
||||
real_or_syn_data[synthetic] += read(fname, format='GSE2', starttime=self.tstart, endtime=self.tstop)
|
||||
orig_or_alternative_data[alternative] += read(fname, format='GSE2', starttime=self.tstart, endtime=self.tstop)
|
||||
except Exception as e:
|
||||
try:
|
||||
real_or_syn_data[synthetic] += read(fname, format='SEGY', starttime=self.tstart,
|
||||
endtime=self.tstop)
|
||||
orig_or_alternative_data[alternative] += read(fname, format='SEGY', starttime=self.tstart,
|
||||
endtime=self.tstop)
|
||||
except Exception as e:
|
||||
warnmsg += '{0}\n{1}\n'.format(fname, e)
|
||||
except SacIOError as se:
|
||||
@@ -519,8 +549,8 @@ class Data(object):
|
||||
def getOriginalWFData(self):
|
||||
return self.wforiginal
|
||||
|
||||
def getSynWFData(self):
|
||||
return self.wfsyn
|
||||
def getAltWFdata(self):
|
||||
return self.wf_alt
|
||||
|
||||
def resetWFData(self):
|
||||
"""
|
||||
|
||||
@@ -280,6 +280,7 @@ def picksdict_from_picks(evt):
|
||||
infile = os.path.join(os.path.expanduser('~'), '.pylot', 'pylot.in')
|
||||
print('Using default input file {}'.format(infile))
|
||||
parameter = PylotParameter(infile)
|
||||
pick.phase_hint = identifyPhase(pick.phase_hint)
|
||||
if pick.phase_hint == 'P':
|
||||
errors = parameter['timeerrorsP']
|
||||
elif pick.phase_hint == 'S':
|
||||
@@ -517,7 +518,7 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
|
||||
arrivals = chooseArrivals(arrivals) # MP MP what is chooseArrivals? It is not defined anywhere
|
||||
for key in arrivals:
|
||||
# P onsets
|
||||
if arrivals[key].has_key('P'):
|
||||
if 'P' in arrivals[key]:
|
||||
try:
|
||||
fm = arrivals[key]['P']['fm']
|
||||
except KeyError as e:
|
||||
@@ -551,7 +552,7 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
|
||||
ss_ms,
|
||||
pweight))
|
||||
# S onsets
|
||||
if arrivals[key].has_key('S') and arrivals[key]['S']['mpp'] is not None:
|
||||
if 'S' in arrivals[key] and arrivals[key]['S']['mpp'] is not None:
|
||||
fm = '?'
|
||||
onset = arrivals[key]['S']['mpp']
|
||||
year = onset.year
|
||||
@@ -670,7 +671,7 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
|
||||
arrivals = chooseArrivals(arrivals) # MP MP what is chooseArrivals? It is not defined anywhere
|
||||
for key in arrivals:
|
||||
# P onsets
|
||||
if arrivals[key].has_key('P') and arrivals[key]['P']['mpp'] is not None:
|
||||
if 'P' in arrivals[key] and arrivals[key]['P']['mpp'] is not None:
|
||||
if arrivals[key]['P']['weight'] < 4:
|
||||
Ponset = arrivals[key]['P']['mpp']
|
||||
pyear = Ponset.year
|
||||
@@ -699,7 +700,7 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
|
||||
fid.write('%-5s P1 %4.0f %02d %02d %02d %02d %05.02f %5.3f -999. 0.00 -999. 0.00\n'
|
||||
% (key, pyear, pmonth, pday, phh, pmm, Pss, pstd))
|
||||
# S onsets
|
||||
if arrivals[key].has_key('S') and arrivals[key]['S']['mpp'] is not None:
|
||||
if 'S' in arrivals[key] and arrivals[key]['S']['mpp'] is not None:
|
||||
if arrivals[key]['S']['weight'] < 4:
|
||||
Sonset = arrivals[key]['S']['mpp']
|
||||
syear = Sonset.year
|
||||
@@ -768,7 +769,7 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
|
||||
usedarrivals = chooseArrivals(arrivals)
|
||||
for key in usedarrivals:
|
||||
# P onsets
|
||||
if usedarrivals[key].has_key('P'):
|
||||
if 'P' in usedarrivals[key]:
|
||||
if usedarrivals[key]['P']['weight'] < 4:
|
||||
n += 1
|
||||
stat = key
|
||||
@@ -782,7 +783,7 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
|
||||
else:
|
||||
fid.write('%-4sP%d%6.2f\n' % (stat, Pweight, Prt))
|
||||
# S onsets
|
||||
if usedarrivals[key].has_key('S'):
|
||||
if 'S' in usedarrivals[key]:
|
||||
if usedarrivals[key]['S']['weight'] < 4:
|
||||
n += 1
|
||||
stat = key
|
||||
@@ -828,13 +829,13 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
|
||||
# prefer manual picks
|
||||
usedarrivals = chooseArrivals(arrivals)
|
||||
for key in usedarrivals:
|
||||
if usedarrivals[key].has_key('P'):
|
||||
if 'P' in usedarrivals[key]:
|
||||
# P onsets
|
||||
if usedarrivals[key]['P']['weight'] < 4:
|
||||
Ponset = usedarrivals[key]['P']['mpp']
|
||||
Prt = Ponset - stime # onset time relative to source time
|
||||
fid.write('%s %6.3f 1 P\n' % (key, Prt))
|
||||
if usedarrivals[key].has_key('S'):
|
||||
if 'S' in usedarrivals[key]:
|
||||
# S onsets
|
||||
if usedarrivals[key]['S']['weight'] < 4:
|
||||
Sonset = usedarrivals[key]['S']['mpp']
|
||||
@@ -879,7 +880,7 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
|
||||
# prefer manual picks
|
||||
usedarrivals = chooseArrivals(arrivals)
|
||||
for key in usedarrivals:
|
||||
if usedarrivals[key].has_key('P'):
|
||||
if 'P' in usedarrivals[key]:
|
||||
if usedarrivals[key]['P']['weight'] < 4 and usedarrivals[key]['P']['fm'] is not None:
|
||||
stat = key
|
||||
for i in range(len(picks)):
|
||||
@@ -961,7 +962,7 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
|
||||
arrivals = chooseArrivals(arrivals) # MP MP what is chooseArrivals? It is not defined anywhere
|
||||
# write phase lines
|
||||
for key in arrivals:
|
||||
if arrivals[key].has_key('P'):
|
||||
if 'P' in arrivals[key]:
|
||||
if arrivals[key]['P']['weight'] < 4 and arrivals[key]['P']['fm'] is not None:
|
||||
stat = key
|
||||
ccode = arrivals[key]['P']['channel']
|
||||
@@ -1014,7 +1015,6 @@ def chooseArrivals(arrivals):
|
||||
:return: arrivals but with the manual picks prefered if possible
|
||||
"""
|
||||
# If len of arrivals is greater than 2 it comes from autopicking so only autopicks are available
|
||||
print("=== CHOOSE ===")
|
||||
if len(arrivals) > 2:
|
||||
return arrivals
|
||||
if arrivals['auto'] and arrivals['manual']:
|
||||
|
||||
@@ -82,8 +82,8 @@ def locate(fnin, parameter=None):
|
||||
:param fnin: external program name
|
||||
:return: None
|
||||
"""
|
||||
exe_path = which('NLLoc', parameter)
|
||||
if exe_path is None:
|
||||
exe_path = os.path.join(parameter['nllocbin'], 'NLLoc')
|
||||
if not os.path.isfile(exe_path):
|
||||
raise NLLocError('NonLinLoc executable not found; check your '
|
||||
'environment variables')
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ from pylot.core.pick.picker import AICPicker, PragPicker
|
||||
from pylot.core.pick.utils import checksignallength, checkZ4S, earllatepicker, \
|
||||
getSNR, fmpicker, checkPonsets, wadaticheck, get_quality_class
|
||||
from pylot.core.util.utils import getPatternLine, gen_Pool, \
|
||||
get_Bool, identifyPhaseID, get_None, correct_iplot
|
||||
get_bool, identifyPhaseID, get_None, correct_iplot
|
||||
|
||||
|
||||
def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, ncores=0, metadata=None, origin=None):
|
||||
@@ -477,7 +477,7 @@ class AutopickStation(object):
|
||||
if self.pickparams["sstart"] < 0:
|
||||
self.pickparams["sstart"] = 0
|
||||
|
||||
if get_Bool(self.pickparams["use_taup"]) is False:
|
||||
if get_bool(self.pickparams["use_taup"]) is False:
|
||||
# correct user mistake where a relative cuttime is selected (pstart < 0) but use of taupy is disabled/ has
|
||||
# not the required parameters
|
||||
exit_taupy()
|
||||
@@ -525,7 +525,7 @@ class AutopickStation(object):
|
||||
:rtype: dict
|
||||
"""
|
||||
|
||||
if get_Bool(self.pickparams['use_taup']) is True and self.origin is not None:
|
||||
if get_bool(self.pickparams['use_taup']) is True and self.origin is not None:
|
||||
try:
|
||||
# modify pstart, pstop, sstart, sstop to be around theoretical onset if taupy should be used,
|
||||
# else do nothing
|
||||
@@ -544,7 +544,7 @@ class AutopickStation(object):
|
||||
|
||||
if self.horizontal_traces_exist():
|
||||
if (self.p_results.weight is not None and self.p_results.weight < 4) or \
|
||||
get_Bool(self.pickparams.get('use_taup')):
|
||||
get_bool(self.pickparams.get('use_taup')):
|
||||
try:
|
||||
self.pick_s_phase()
|
||||
except MissingTraceException as mte:
|
||||
@@ -936,7 +936,7 @@ class AutopickStation(object):
|
||||
"minFMSNR"]:
|
||||
# if SNR is high enough, try to determine first motion of onset
|
||||
self.set_current_figure('fm_picker')
|
||||
self.p_results.fm = fmpicker(self.zstream, z_copy, self.pickparams["fmpickwin"], self.p_results.mpp,
|
||||
self.p_results.fm = fmpicker(self.zstream.copy(), z_copy, self.pickparams["fmpickwin"], self.p_results.mpp,
|
||||
self.iplot, self.current_figure, self.current_linecolor)
|
||||
msg = "autopickstation: P-weight: {}, SNR: {}, SNR[dB]: {}, Polarity: {}"
|
||||
msg = msg.format(self.p_results.weight, self.p_results.snr, self.p_results.snrdb, self.p_results.fm)
|
||||
@@ -1148,7 +1148,7 @@ class AutopickStation(object):
|
||||
''.format(self.s_results.weight, self.s_results.snr, self.s_results.snrdb))
|
||||
|
||||
def pick_s_phase(self):
|
||||
if get_Bool(self.pickparams.get('use_taup')) is True:
|
||||
if get_bool(self.pickparams.get('use_taup')) is True:
|
||||
cuttimesh = (self.pickparams.get('sstart'), self.pickparams.get('sstop'))
|
||||
else:
|
||||
# determine time window for calculating CF after P onset
|
||||
|
||||
@@ -16,10 +16,9 @@ autoregressive prediction: application ot local and regional distances, Geophys.
|
||||
|
||||
:author: MAGS2 EP3 working group
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
from obspy.core import Stream
|
||||
from scipy import signal
|
||||
from obspy.core import Stream
|
||||
|
||||
|
||||
class CharacteristicFunction(object):
|
||||
@@ -259,7 +258,7 @@ class HOScf(CharacteristicFunction):
|
||||
"""
|
||||
Function to calculate skewness (statistics of order 3) or kurtosis
|
||||
(statistics of order 4), using one long moving window, as published
|
||||
in Kueperkoch et al. (2010).
|
||||
in Kueperkoch et al. (2010), or order 2, i.e. STA/LTA.
|
||||
:param data: data, time series (whether seismogram or CF)
|
||||
:type data: tuple
|
||||
:return: HOS cf
|
||||
@@ -276,28 +275,47 @@ class HOScf(CharacteristicFunction):
|
||||
elif self.getOrder() == 4: # this is kurtosis
|
||||
y = np.power(xnp, 4)
|
||||
y1 = np.power(xnp, 2)
|
||||
elif self.getOrder() == 2: # this is variance, used for STA/LTA processing
|
||||
y = np.power(xnp, 2)
|
||||
y1 = np.power(xnp, 2)
|
||||
|
||||
# Initialisation
|
||||
# t2: long term moving window
|
||||
ilta = int(round(self.getTime2() / self.getIncrement()))
|
||||
ista = int(round((self.getTime2() / 10) / self.getIncrement())) # TODO: still hard coded!!
|
||||
lta = y[0]
|
||||
lta1 = y1[0]
|
||||
sta = y[0]
|
||||
# moving windows
|
||||
LTA = np.zeros(len(xnp))
|
||||
STA = np.zeros(len(xnp))
|
||||
for j in range(0, len(xnp)):
|
||||
if j < 4:
|
||||
LTA[j] = 0
|
||||
STA[j] = 0
|
||||
elif j <= ista:
|
||||
lta = (y[j] + lta * (j - 1)) / j
|
||||
if self.getOrder() == 2:
|
||||
sta = (y[j] + sta * (j - 1)) / j
|
||||
# elif j < 4:
|
||||
elif j <= ilta:
|
||||
lta = (y[j] + lta * (j - 1)) / j
|
||||
lta1 = (y1[j] + lta1 * (j - 1)) / j
|
||||
if self.getOrder() == 2:
|
||||
sta = (y[j] - y[j - ista]) / ista + sta
|
||||
else:
|
||||
lta = (y[j] - y[j - ilta]) / ilta + lta
|
||||
lta1 = (y1[j] - y1[j - ilta]) / ilta + lta1
|
||||
if self.getOrder() == 2:
|
||||
sta = (y[j] - y[j - ista]) / ista + sta
|
||||
# define LTA
|
||||
if self.getOrder() == 3:
|
||||
LTA[j] = lta / np.power(lta1, 1.5)
|
||||
elif self.getOrder() == 4:
|
||||
LTA[j] = lta / np.power(lta1, 2)
|
||||
else:
|
||||
LTA[j] = lta
|
||||
STA[j] = sta
|
||||
|
||||
# remove NaN's with first not-NaN-value,
|
||||
# so autopicker doesnt pick discontinuity at start of the trace
|
||||
@@ -306,7 +324,10 @@ class HOScf(CharacteristicFunction):
|
||||
first = ind[0]
|
||||
LTA[:first] = LTA[first]
|
||||
|
||||
self.cf = LTA
|
||||
if self.getOrder() > 2:
|
||||
self.cf = LTA
|
||||
else: # order 2 means STA/LTA!
|
||||
self.cf = STA / LTA
|
||||
self.xcf = x
|
||||
|
||||
|
||||
|
||||
@@ -336,7 +336,7 @@ class AICPicker(AutoPicker):
|
||||
self.slope = 1 / (len(dataslope) * self.Data[0].stats.delta) * (datafit[-1] - datafit[0])
|
||||
# normalize slope to maximum of cf to make it unit independent
|
||||
self.slope /= aicsmooth[iaicmax]
|
||||
except ValueError as e:
|
||||
except Exception as e:
|
||||
print("AICPicker: Problems with data fitting! {}".format(e))
|
||||
|
||||
else:
|
||||
|
||||
@@ -15,7 +15,7 @@ import numpy as np
|
||||
from obspy.core import Stream, UTCDateTime
|
||||
from scipy.signal import argrelmax
|
||||
|
||||
from pylot.core.util.utils import get_Bool, get_None, SetChannelComponents
|
||||
from pylot.core.util.utils import get_bool, get_None, SetChannelComponents
|
||||
|
||||
|
||||
def earllatepicker(X, nfac, TSNR, Pick1, iplot=0, verbosity=1, fig=None, linecolor='k'):
|
||||
@@ -62,8 +62,8 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=0, verbosity=1, fig=None, linecol
|
||||
plt_flag = 0
|
||||
try:
|
||||
iplot = int(iplot)
|
||||
except:
|
||||
if get_Bool(iplot):
|
||||
except ValueError:
|
||||
if get_bool(iplot):
|
||||
iplot = 2
|
||||
else:
|
||||
iplot = 0
|
||||
@@ -275,7 +275,7 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=0, fig=None, linecolor='k'):
|
||||
try:
|
||||
P1 = np.polyfit(xslope1, xraw[islope1], 1)
|
||||
datafit1 = np.polyval(P1, xslope1)
|
||||
except ValueError as e:
|
||||
except Exception as e:
|
||||
print("fmpicker: Problems with data fit! {}".format(e))
|
||||
print("Skip first motion determination!")
|
||||
return FM
|
||||
@@ -321,7 +321,7 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=0, fig=None, linecolor='k'):
|
||||
try:
|
||||
P2 = np.polyfit(xslope2, xfilt[islope2], 1)
|
||||
datafit2 = np.polyval(P2, xslope2)
|
||||
except ValueError as e:
|
||||
except Exception as e:
|
||||
emsg = 'fmpicker: polyfit failed: {}'.format(e)
|
||||
print(emsg)
|
||||
return FM
|
||||
@@ -816,7 +816,7 @@ def checksignallength(X, pick, minsiglength, pickparams, iplot=0, fig=None, line
|
||||
try:
|
||||
iplot = int(iplot)
|
||||
except:
|
||||
if get_Bool(iplot):
|
||||
if get_bool(iplot):
|
||||
iplot = 2
|
||||
else:
|
||||
iplot = 0
|
||||
@@ -1130,7 +1130,7 @@ def checkZ4S(X, pick, pickparams, iplot, fig=None, linecolor='k'):
|
||||
try:
|
||||
iplot = int(iplot)
|
||||
except:
|
||||
if get_Bool(iplot):
|
||||
if get_bool(iplot):
|
||||
iplot = 2
|
||||
else:
|
||||
iplot = 0
|
||||
@@ -1499,7 +1499,7 @@ def get_pickparams(pickparam):
|
||||
first_motion_params = dict(zip(first_motion_names, fm_parameter_values))
|
||||
signal_length_params = dict(zip(signal_length_names, sl_parameter_values))
|
||||
|
||||
p_params['use_taup'] = get_Bool(p_params['use_taup'])
|
||||
p_params['use_taup'] = get_bool(p_params['use_taup'])
|
||||
|
||||
return p_params, s_params, first_motion_params, signal_length_params
|
||||
|
||||
|
||||
@@ -75,7 +75,6 @@ class Array_map(QtWidgets.QWidget):
|
||||
|
||||
self._style = None if not hasattr(parent, '_style') else parent._style
|
||||
|
||||
self.show()
|
||||
|
||||
def init_map(self):
|
||||
self.init_colormap()
|
||||
@@ -464,17 +463,19 @@ class Array_map(QtWidgets.QWidget):
|
||||
transform=ccrs.PlateCarree(), label='deleted'))
|
||||
|
||||
def openPickDlg(self, ind):
|
||||
data = self._parent.get_data().getWFData()
|
||||
wfdata = self._parent.get_data().getWFData()
|
||||
wfdata_comp = self._parent.get_data().getWFDataComp()
|
||||
for index in ind:
|
||||
network, station = self._station_onpick_ids[index].split('.')[:2]
|
||||
pyl_mw = self._parent
|
||||
try:
|
||||
data = data.select(station=station)
|
||||
if not data:
|
||||
wfdata = wfdata.select(station=station)
|
||||
wfdata_comp = wfdata_comp.select(station=station)
|
||||
if not wfdata:
|
||||
self._warn('No data for station {}'.format(station))
|
||||
return
|
||||
pickDlg = PickDlg(self._parent, parameter=self.parameter,
|
||||
data=data, network=network, station=station,
|
||||
data=wfdata.copy(), data_compare=wfdata_comp.copy(), network=network, station=station,
|
||||
picks=self._parent.get_current_event().getPick(station),
|
||||
autopicks=self._parent.get_current_event().getAutopick(station),
|
||||
filteroptions=self._parent.filteroptions, metadata=self.metadata,
|
||||
|
||||
@@ -271,7 +271,7 @@ class Metadata(object):
|
||||
continue
|
||||
invtype, robj = self._read_metadata_file(os.path.join(path_to_inventory, fname))
|
||||
try:
|
||||
robj.get_coordinates(station_seed_id)
|
||||
# robj.get_coordinates(station_seed_id) # TODO: Commented out, failed with Parser, is this needed?
|
||||
self.inventory_files[fname] = {'invtype': invtype,
|
||||
'data': robj}
|
||||
if station_seed_id in self.seed_ids.keys():
|
||||
|
||||
@@ -26,9 +26,7 @@ elif system_name == "Windows":
|
||||
# suffix for phase name if not phase identified by last letter (P, p, etc.)
|
||||
ALTSUFFIX = ['diff', 'n', 'g', '1', '2', '3']
|
||||
|
||||
FILTERDEFAULTS = readDefaultFilterInformation(os.path.join(os.path.expanduser('~'),
|
||||
'.pylot',
|
||||
'pylot.in'))
|
||||
FILTERDEFAULTS = readDefaultFilterInformation()
|
||||
|
||||
TIMEERROR_DEFAULTS = os.path.join(os.path.expanduser('~'),
|
||||
'.pylot',
|
||||
|
||||
@@ -56,7 +56,7 @@ def which(program, parameter):
|
||||
nllocpath = ":" + parameter.get('nllocbin')
|
||||
os.environ['PATH'] += nllocpath
|
||||
except Exception as e:
|
||||
print(e.message)
|
||||
print(e)
|
||||
|
||||
def is_exe(fpath):
|
||||
return os.path.exists(fpath) and os.access(fpath, os.X_OK)
|
||||
|
||||
@@ -41,7 +41,8 @@ class Thread(QThread):
|
||||
exctype, value = sys.exc_info()[:2]
|
||||
self._executedErrorInfo = '{} {} {}'. \
|
||||
format(exctype, value, traceback.format_exc())
|
||||
sys.stdout = self.old_stdout
|
||||
if self.redirect_stdout:
|
||||
sys.stdout = self.old_stdout
|
||||
|
||||
def showProgressbar(self):
|
||||
if self.progressText:
|
||||
|
||||
@@ -37,15 +37,14 @@ def getAutoFilteroptions(phase, parameter):
|
||||
return filteroptions
|
||||
|
||||
|
||||
def readDefaultFilterInformation(fname):
|
||||
def readDefaultFilterInformation():
|
||||
"""
|
||||
Read default filter information from pylot.in file
|
||||
:param fname: path to pylot.in file
|
||||
:type fname: str
|
||||
:return: dictionary containing the defailt filter information
|
||||
:rtype: dict
|
||||
"""
|
||||
pparam = PylotParameter(fname)
|
||||
pparam = PylotParameter()
|
||||
pparam.reset_defaults()
|
||||
return readFilterInformation(pparam)
|
||||
|
||||
|
||||
@@ -328,7 +327,7 @@ def get_None(value):
|
||||
return value
|
||||
|
||||
|
||||
def get_Bool(value):
|
||||
def get_bool(value):
|
||||
"""
|
||||
Convert string representations of bools to their true boolean value
|
||||
:param value:
|
||||
@@ -336,13 +335,14 @@ def get_Bool(value):
|
||||
:return: true boolean value
|
||||
:rtype: bool
|
||||
"""
|
||||
if value in ['True', 'true']:
|
||||
if type(value) is bool:
|
||||
return value
|
||||
elif value in ['True', 'true']:
|
||||
return True
|
||||
elif value in ['False', 'false']:
|
||||
return False
|
||||
else:
|
||||
return value
|
||||
|
||||
return bool(value)
|
||||
|
||||
def four_digits(year):
|
||||
"""
|
||||
@@ -1169,7 +1169,7 @@ def correct_iplot(iplot):
|
||||
try:
|
||||
iplot = int(iplot)
|
||||
except ValueError:
|
||||
if get_Bool(iplot):
|
||||
if get_bool(iplot):
|
||||
iplot = 2
|
||||
else:
|
||||
iplot = 0
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Wed Mar 19 11:27:35 2014
|
||||
|
||||
@author: sebastianw
|
||||
"""
|
||||
|
||||
@@ -54,7 +53,7 @@ from pylot.core.util.utils import prepTimeAxis, full_range, demeanTrace, isSorte
|
||||
pick_linestyle_plt, pick_color_plt, \
|
||||
check4rotated, check4doubled, merge_stream, identifyPhase, \
|
||||
loopIdentifyPhase, trim_station_components, transformFilteroptions2String, \
|
||||
identifyPhaseID, get_Bool, get_None, pick_color, getAutoFilteroptions, SetChannelComponents, \
|
||||
identifyPhaseID, get_bool, get_None, pick_color, getAutoFilteroptions, SetChannelComponents, \
|
||||
station_id_remove_channel
|
||||
from autoPyLoT import autoPyLoT
|
||||
from pylot.core.util.thread import Thread
|
||||
@@ -794,7 +793,7 @@ class WaveformWidgetPG(QtWidgets.QWidget):
|
||||
|
||||
def connect_signals(self):
|
||||
self.qcombo_processed.activated.connect(self.parent().newWF)
|
||||
self.syn_checkbox.clicked.connect(self.parent().newWF)
|
||||
self.comp_checkbox.clicked.connect(self.parent().newWF)
|
||||
|
||||
def init_labels(self):
|
||||
self.label_layout.addWidget(self.status_label)
|
||||
@@ -805,13 +804,13 @@ class WaveformWidgetPG(QtWidgets.QWidget):
|
||||
# use widgets as placeholder, so that child widgets keep position when others are hidden
|
||||
mid_layout = QHBoxLayout()
|
||||
right_layout = QHBoxLayout()
|
||||
mid_layout.addWidget(self.syn_checkbox)
|
||||
mid_layout.addWidget(self.comp_checkbox)
|
||||
right_layout.addWidget(self.qcombo_processed)
|
||||
mid_widget.setLayout(mid_layout)
|
||||
right_widget.setLayout(right_layout)
|
||||
self.label_layout.addWidget(mid_widget)
|
||||
self.label_layout.addWidget(right_widget)
|
||||
self.syn_checkbox.setLayoutDirection(Qt.RightToLeft)
|
||||
self.comp_checkbox.setLayoutDirection(Qt.RightToLeft)
|
||||
self.label_layout.setStretch(0, 4)
|
||||
self.label_layout.setStretch(1, 0)
|
||||
self.label_layout.setStretch(2, 0)
|
||||
@@ -826,7 +825,7 @@ class WaveformWidgetPG(QtWidgets.QWidget):
|
||||
label = QtWidgets.QLabel()
|
||||
self.perm_labels.append(label)
|
||||
self.qcombo_processed = QtWidgets.QComboBox()
|
||||
self.syn_checkbox = QtWidgets.QCheckBox('synthetics')
|
||||
self.comp_checkbox = QtWidgets.QCheckBox('Load comparison data')
|
||||
self.addQCboxItem('processed', 'green')
|
||||
self.addQCboxItem('raw', 'black')
|
||||
# self.perm_qcbox_right.setAlignment(2)
|
||||
@@ -835,9 +834,11 @@ class WaveformWidgetPG(QtWidgets.QWidget):
|
||||
def getPlotDict(self):
|
||||
return self.plotdict
|
||||
|
||||
def activateObspyDMToptions(self, activate):
|
||||
self.syn_checkbox.setVisible(activate)
|
||||
self.qcombo_processed.setVisible(activate)
|
||||
def activateObspyDMToptions(self, activate: bool) -> None:
|
||||
self.qcombo_processed.setEnabled(activate)
|
||||
|
||||
def activateCompareOptions(self, activate: bool) -> None:
|
||||
self.comp_checkbox.setEnabled(activate)
|
||||
|
||||
def setPermText(self, number, text=None, color='black'):
|
||||
if not 0 <= number < len(self.perm_labels):
|
||||
@@ -861,10 +862,8 @@ class WaveformWidgetPG(QtWidgets.QWidget):
|
||||
def clearPlotDict(self):
|
||||
self.plotdict = dict()
|
||||
|
||||
def plotWFData(self, wfdata, wfsyn=None, title=None, zoomx=None, zoomy=None,
|
||||
noiselevel=None, scaleddata=False, mapping=True,
|
||||
component='*', nth_sample=1, iniPick=None, verbosity=0,
|
||||
method='normal', gain=1.):
|
||||
def plotWFData(self, wfdata, wfsyn=None, title=None, scaleddata=False, mapping=True,
|
||||
component='*', nth_sample=1, verbosity=0, method='normal', gain=1., shift_syn=0.2):
|
||||
if not wfdata:
|
||||
print('Nothing to plot.')
|
||||
return
|
||||
@@ -947,7 +946,7 @@ class WaveformWidgetPG(QtWidgets.QWidget):
|
||||
[time for index, time in enumerate(time_ax_syn) if not index % nth_sample] if st_syn else [])
|
||||
trace.data = np.array(
|
||||
[datum * gain + n for index, datum in enumerate(trace.data) if not index % nth_sample])
|
||||
trace_syn.data = np.array([datum + n for index, datum in enumerate(trace_syn.data)
|
||||
trace_syn.data = np.array([datum + n + shift_syn for index, datum in enumerate(trace_syn.data)
|
||||
if not index % nth_sample] if st_syn else [])
|
||||
plots.append((times, trace.data,
|
||||
times_syn, trace_syn.data))
|
||||
@@ -1136,12 +1135,12 @@ class PylotCanvas(FigureCanvas):
|
||||
ax.set_xlim(self.cur_xlim)
|
||||
ax.set_ylim(self.cur_ylim)
|
||||
self.refreshPickDlgText()
|
||||
ax.figure.canvas.draw()
|
||||
ax.figure.canvas.draw_idle()
|
||||
|
||||
def panRelease(self, gui_event):
|
||||
self.press = None
|
||||
self.press_rel = None
|
||||
self.figure.canvas.draw()
|
||||
self.figure.canvas.draw_idle()
|
||||
|
||||
def panZoom(self, gui_event, threshold=2., factor=1.1):
|
||||
if not gui_event.x and not gui_event.y:
|
||||
@@ -1359,11 +1358,15 @@ class PylotCanvas(FigureCanvas):
|
||||
plot_positions[channel] = plot_pos
|
||||
return plot_positions
|
||||
|
||||
def plotWFData(self, wfdata, title=None, zoomx=None, zoomy=None,
|
||||
def plotWFData(self, wfdata, wfdata_compare=None, title=None, zoomx=None, zoomy=None,
|
||||
noiselevel=None, scaleddata=False, mapping=True,
|
||||
component='*', nth_sample=1, iniPick=None, verbosity=0,
|
||||
plot_additional=False, additional_channel=None, scaleToChannel=None,
|
||||
snr=None):
|
||||
def get_wf_dict(data: Stream = Stream(), linecolor = 'k', offset: float = 0., **plot_kwargs):
|
||||
return dict(data=data, linecolor=linecolor, offset=offset, plot_kwargs=plot_kwargs)
|
||||
|
||||
|
||||
ax = self.axes[0]
|
||||
ax.cla()
|
||||
|
||||
@@ -1374,21 +1377,33 @@ class PylotCanvas(FigureCanvas):
|
||||
settings = QSettings()
|
||||
compclass = SetChannelComponents.from_qsettings(settings)
|
||||
|
||||
linecolor = (0., 0., 0., 1.) if not self.style else self.style['linecolor']['rgba_mpl']
|
||||
|
||||
plot_streams = dict(wfdata=get_wf_dict(linecolor=linecolor, linewidth=0.7),
|
||||
wfdata_comp=get_wf_dict(offset=0.1, linecolor='b', alpha=0.7, linewidth=0.5))
|
||||
|
||||
if not component == '*':
|
||||
alter_comp = compclass.getCompPosition(component)
|
||||
# alter_comp = str(alter_comp[0])
|
||||
|
||||
st_select = wfdata.select(component=component)
|
||||
st_select += wfdata.select(component=alter_comp)
|
||||
plot_streams['wfdata']['data'] = wfdata.select(component=component)
|
||||
plot_streams['wfdata']['data'] += wfdata.select(component=alter_comp)
|
||||
if wfdata_compare:
|
||||
plot_streams['wfdata_comp']['data'] = wfdata_compare.select(component=component)
|
||||
plot_streams['wfdata_comp']['data'] += wfdata_compare.select(component=alter_comp)
|
||||
else:
|
||||
st_select = wfdata
|
||||
plot_streams['wfdata']['data'] = wfdata
|
||||
if wfdata_compare:
|
||||
plot_streams['wfdata_comp']['data'] = wfdata_compare
|
||||
|
||||
st_main = plot_streams['wfdata']['data']
|
||||
|
||||
if mapping:
|
||||
plot_positions = self.calcPlotPositions(st_select, compclass)
|
||||
plot_positions = self.calcPlotPositions(st_main, compclass)
|
||||
|
||||
# list containing tuples of network, station, channel and plot position (for sorting)
|
||||
nslc = []
|
||||
for plot_pos, trace in enumerate(st_select):
|
||||
for plot_pos, trace in enumerate(st_main):
|
||||
if not trace.stats.channel[-1] in ['Z', 'N', 'E', '1', '2', '3']:
|
||||
print('Warning: Unrecognized channel {}'.format(trace.stats.channel))
|
||||
continue
|
||||
@@ -1396,44 +1411,48 @@ class PylotCanvas(FigureCanvas):
|
||||
nslc.sort()
|
||||
nslc.reverse()
|
||||
|
||||
linecolor = (0., 0., 0., 1.) if not self.style else self.style['linecolor']['rgba_mpl']
|
||||
|
||||
for n, seed_id in enumerate(nslc):
|
||||
network, station, location, channel = seed_id.split('.')
|
||||
st = st_select.select(id=seed_id)
|
||||
trace = st[0].copy()
|
||||
if mapping:
|
||||
n = plot_positions[trace.stats.channel]
|
||||
if n > nmax:
|
||||
nmax = n
|
||||
if verbosity:
|
||||
msg = 'plotting %s channel of station %s' % (channel, station)
|
||||
print(msg)
|
||||
stime = trace.stats.starttime - wfstart
|
||||
time_ax = prepTimeAxis(stime, trace)
|
||||
if time_ax is not None:
|
||||
if scaleToChannel:
|
||||
st_scale = wfdata.select(channel=scaleToChannel)
|
||||
if st_scale:
|
||||
tr = st_scale[0]
|
||||
for wf_name, wf_dict in plot_streams.items():
|
||||
st_select = wf_dict.get('data')
|
||||
if not st_select:
|
||||
continue
|
||||
st = st_select.select(id=seed_id)
|
||||
trace = st[0].copy()
|
||||
if mapping:
|
||||
n = plot_positions[trace.stats.channel]
|
||||
if n > nmax:
|
||||
nmax = n
|
||||
if verbosity:
|
||||
msg = 'plotting %s channel of station %s' % (channel, station)
|
||||
print(msg)
|
||||
stime = trace.stats.starttime - wfstart
|
||||
time_ax = prepTimeAxis(stime, trace)
|
||||
if time_ax is not None:
|
||||
if scaleToChannel:
|
||||
st_scale = wfdata.select(channel=scaleToChannel)
|
||||
if st_scale:
|
||||
tr = st_scale[0]
|
||||
trace.detrend('constant')
|
||||
trace.normalize(np.max(np.abs(tr.data)) * 2)
|
||||
scaleddata = True
|
||||
if not scaleddata:
|
||||
trace.detrend('constant')
|
||||
trace.normalize(np.max(np.abs(tr.data)) * 2)
|
||||
scaleddata = True
|
||||
if not scaleddata:
|
||||
trace.detrend('constant')
|
||||
trace.normalize(np.max(np.abs(trace.data)) * 2)
|
||||
trace.normalize(np.max(np.abs(trace.data)) * 2)
|
||||
|
||||
times = [time for index, time in enumerate(time_ax) if not index % nth_sample]
|
||||
data = [datum + n for index, datum in enumerate(trace.data) if not index % nth_sample]
|
||||
ax.axhline(n, color="0.5", lw=0.5)
|
||||
ax.plot(times, data, color=linecolor, linewidth=0.7)
|
||||
if noiselevel is not None:
|
||||
for level in [-noiselevel[channel], noiselevel[channel]]:
|
||||
ax.plot([time_ax[0], time_ax[-1]],
|
||||
[n + level, n + level],
|
||||
color=linecolor,
|
||||
linestyle='dashed')
|
||||
self.setPlotDict(n, seed_id)
|
||||
offset = wf_dict.get('offset')
|
||||
|
||||
times = [time for index, time in enumerate(time_ax) if not index % nth_sample]
|
||||
data = [datum + n + offset for index, datum in enumerate(trace.data) if not index % nth_sample]
|
||||
ax.axhline(n, color="0.5", lw=0.5)
|
||||
ax.plot(times, data, color=wf_dict.get('linecolor'), **wf_dict.get('plot_kwargs'))
|
||||
if noiselevel is not None:
|
||||
for level in [-noiselevel[channel], noiselevel[channel]]:
|
||||
ax.plot([time_ax[0], time_ax[-1]],
|
||||
[n + level, n + level],
|
||||
color=wf_dict.get('linecolor'),
|
||||
linestyle='dashed')
|
||||
self.setPlotDict(n, seed_id)
|
||||
if plot_additional and additional_channel:
|
||||
compare_stream = wfdata.select(channel=additional_channel)
|
||||
if compare_stream:
|
||||
@@ -1660,8 +1679,8 @@ class PhaseDefaults(QtWidgets.QDialog):
|
||||
class PickDlg(QDialog):
|
||||
update_picks = QtCore.Signal(dict)
|
||||
|
||||
def __init__(self, parent=None, data=None, station=None, network=None, location=None, picks=None,
|
||||
autopicks=None, rotate=False, parameter=None, embedded=False, metadata=None,
|
||||
def __init__(self, parent=None, data=None, data_compare=None, station=None, network=None, location=None, picks=None,
|
||||
autopicks=None, rotate=False, parameter=None, embedded=False, metadata=None, show_comp_data=False,
|
||||
event=None, filteroptions=None, model=None, wftype=None):
|
||||
super(PickDlg, self).__init__(parent, Qt.Window)
|
||||
self.orig_parent = parent
|
||||
@@ -1670,6 +1689,7 @@ class PickDlg(QDialog):
|
||||
# initialize attributes
|
||||
self.parameter = parameter
|
||||
self._embedded = embedded
|
||||
self.showCompData = show_comp_data
|
||||
self.station = station
|
||||
self.network = network
|
||||
self.location = location
|
||||
@@ -1708,22 +1728,6 @@ class PickDlg(QDialog):
|
||||
else:
|
||||
self.filteroptions = FILTERDEFAULTS
|
||||
self.pick_block = False
|
||||
self.nextStation = QtWidgets.QCheckBox('Continue with next station ')
|
||||
|
||||
# comparison channel
|
||||
self.compareChannel = QtWidgets.QComboBox()
|
||||
self.compareChannel.activated.connect(self.resetPlot)
|
||||
|
||||
# scale channel
|
||||
self.scaleChannel = QtWidgets.QComboBox()
|
||||
self.scaleChannel.activated.connect(self.resetPlot)
|
||||
|
||||
# initialize panning attributes
|
||||
self.press = None
|
||||
self.xpress = None
|
||||
self.ypress = None
|
||||
self.cur_xlim = None
|
||||
self.cur_ylim = None
|
||||
|
||||
# set attribute holding data
|
||||
if data is None or not data:
|
||||
@@ -1736,6 +1740,31 @@ class PickDlg(QDialog):
|
||||
raise Exception(errmsg)
|
||||
else:
|
||||
self.data = data
|
||||
self.data_compare = data_compare
|
||||
|
||||
self.nextStation = QtWidgets.QCheckBox('Continue with next station ')
|
||||
|
||||
# comparison channel
|
||||
self.referenceChannel = QtWidgets.QComboBox()
|
||||
self.referenceChannel.activated.connect(self.resetPlot)
|
||||
|
||||
# comparison channel
|
||||
self.compareCB = QtWidgets.QCheckBox()
|
||||
self.compareCB.setChecked(self.showCompData)
|
||||
self.compareCB.clicked.connect(self.switchCompData)
|
||||
self.compareCB.clicked.connect(self.resetPlot)
|
||||
self.compareCB.setVisible(bool(self.data_compare))
|
||||
|
||||
# scale channel
|
||||
self.scaleChannel = QtWidgets.QComboBox()
|
||||
self.scaleChannel.activated.connect(self.resetPlot)
|
||||
|
||||
# initialize panning attributes
|
||||
self.press = None
|
||||
self.xpress = None
|
||||
self.ypress = None
|
||||
self.cur_xlim = None
|
||||
self.cur_ylim = None
|
||||
|
||||
self.stime, self.etime = full_range(self.getWFData())
|
||||
|
||||
@@ -1748,12 +1777,12 @@ class PickDlg(QDialog):
|
||||
self.setupUi()
|
||||
|
||||
# fill compare and scale channels
|
||||
self.compareChannel.addItem('-', None)
|
||||
self.referenceChannel.addItem('-', None)
|
||||
self.scaleChannel.addItem('individual', None)
|
||||
|
||||
for trace in self.getWFData():
|
||||
channel = trace.stats.channel
|
||||
self.compareChannel.addItem(channel, trace)
|
||||
self.referenceChannel.addItem(channel, trace)
|
||||
if not channel[-1] in ['Z', 'N', 'E', '1', '2', '3']:
|
||||
print('Skipping unknown channel for scaling: {}'.format(channel))
|
||||
continue
|
||||
@@ -1770,7 +1799,7 @@ class PickDlg(QDialog):
|
||||
if self.wftype is not None:
|
||||
title += ' | ({})'.format(self.wftype)
|
||||
|
||||
self.multicompfig.plotWFData(wfdata=self.getWFData(),
|
||||
self.multicompfig.plotWFData(wfdata=self.getWFData(), wfdata_compare=self.getWFDataComp(),
|
||||
title=title)
|
||||
|
||||
self.multicompfig.setZoomBorders2content()
|
||||
@@ -1787,7 +1816,7 @@ class PickDlg(QDialog):
|
||||
|
||||
# init expected picks using obspy Taup
|
||||
try:
|
||||
if self.metadata and model is not None:
|
||||
if self.metadata and model != "None":
|
||||
self.model = TauPyModel(model)
|
||||
self.get_arrivals()
|
||||
self.drawArrivals()
|
||||
@@ -1877,7 +1906,7 @@ class PickDlg(QDialog):
|
||||
self.sChannels.triggered.connect(self.updateChannelSettingsS)
|
||||
|
||||
settings = QSettings()
|
||||
self.autoFilterAction.setChecked(get_Bool(settings.value('autoFilter')))
|
||||
self.autoFilterAction.setChecked(get_bool(settings.value('autoFilter')))
|
||||
|
||||
# create other widget elements
|
||||
phaseitems = [None] + list(FILTERDEFAULTS.keys())
|
||||
@@ -1946,8 +1975,11 @@ class PickDlg(QDialog):
|
||||
_dialtoolbar.addWidget(est_label)
|
||||
_dialtoolbar.addWidget(self.plot_arrivals_button)
|
||||
_dialtoolbar.addSeparator()
|
||||
_dialtoolbar.addWidget(QtWidgets.QLabel('Compare to channel: '))
|
||||
_dialtoolbar.addWidget(self.compareChannel)
|
||||
_dialtoolbar.addWidget(QtWidgets.QLabel('Plot reference channel: '))
|
||||
_dialtoolbar.addWidget(self.referenceChannel)
|
||||
_dialtoolbar.addSeparator()
|
||||
_dialtoolbar.addWidget(QtWidgets.QLabel('Compare: '))
|
||||
_dialtoolbar.addWidget(self.compareCB)
|
||||
_dialtoolbar.addSeparator()
|
||||
_dialtoolbar.addWidget(QtWidgets.QLabel('Scaling: '))
|
||||
_dialtoolbar.addWidget(self.scaleChannel)
|
||||
@@ -2282,7 +2314,7 @@ class PickDlg(QDialog):
|
||||
def activatePicking(self):
|
||||
self.leave_rename_phase()
|
||||
self.renamePhaseAction.setEnabled(False)
|
||||
self.compareChannel.setEnabled(False)
|
||||
self.referenceChannel.setEnabled(False)
|
||||
self.scaleChannel.setEnabled(False)
|
||||
phase = self.currentPhase
|
||||
phaseID = self.getPhaseID(phase)
|
||||
@@ -2314,7 +2346,7 @@ class PickDlg(QDialog):
|
||||
self.disconnectPressEvent()
|
||||
self.multicompfig.connectEvents()
|
||||
self.renamePhaseAction.setEnabled(True)
|
||||
self.compareChannel.setEnabled(True)
|
||||
self.referenceChannel.setEnabled(True)
|
||||
self.scaleChannel.setEnabled(True)
|
||||
self.connect_pick_delete()
|
||||
self.draw()
|
||||
@@ -2356,7 +2388,7 @@ class PickDlg(QDialog):
|
||||
settings = QSettings()
|
||||
phaseID = self.getPhaseID(phase)
|
||||
|
||||
if get_Bool(settings.value('useGuiFilter')) or gui_filter:
|
||||
if get_bool(settings.value('useGuiFilter')) or gui_filter:
|
||||
filteroptions = self.filteroptions[phaseID]
|
||||
else:
|
||||
filteroptions = getAutoFilteroptions(phaseID, self.parameter)
|
||||
@@ -2387,6 +2419,12 @@ class PickDlg(QDialog):
|
||||
def getWFData(self):
|
||||
return self.data
|
||||
|
||||
def getWFDataComp(self):
|
||||
if self.showCompData:
|
||||
return self.data_compare
|
||||
else:
|
||||
return Stream()
|
||||
|
||||
def selectWFData(self, channel):
|
||||
component = channel[-1].upper()
|
||||
wfdata = Stream()
|
||||
@@ -2508,24 +2546,33 @@ class PickDlg(QDialog):
|
||||
|
||||
stime = self.getStartTime()
|
||||
|
||||
# copy data for plotting
|
||||
data = self.getWFData().copy()
|
||||
data = self.getPickPhases(data, phase)
|
||||
data.normalize()
|
||||
if not data:
|
||||
# copy wfdata for plotting
|
||||
wfdata = self.getWFData().copy()
|
||||
wfdata_comp = self.getWFDataComp().copy()
|
||||
wfdata = self.getPickPhases(wfdata, phase)
|
||||
wfdata_comp = self.getPickPhases(wfdata_comp, phase)
|
||||
for wfd in [wfdata, wfdata_comp]:
|
||||
if wfd:
|
||||
wfd.normalize()
|
||||
|
||||
if not wfdata:
|
||||
QtWidgets.QMessageBox.warning(self, 'No channel to plot',
|
||||
'No channel to plot for phase: {}.'.format(phase))
|
||||
'No channel to plot for phase: {}. '
|
||||
'Make sure to select the correct channels for P and S '
|
||||
'in the menu in the top panel.'.format(phase))
|
||||
self.leave_picking_mode()
|
||||
return
|
||||
|
||||
# filter data and trace on which is picked prior to determination of SNR
|
||||
# filter wfdata and trace on which is picked prior to determination of SNR
|
||||
filterphase = self.currentFilterPhase()
|
||||
if filterphase:
|
||||
filteroptions = self.getFilterOptions(filterphase).parseFilterOptions()
|
||||
try:
|
||||
data.detrend('linear')
|
||||
data.filter(**filteroptions)
|
||||
# wfdata.filter(**filteroptions)# MP MP removed filtering of original data
|
||||
for wfd in [wfdata, wfdata_comp]:
|
||||
if wfd:
|
||||
wfd.detrend('linear')
|
||||
wfd.filter(**filteroptions)
|
||||
# wfdata.filter(**filteroptions)# MP MP removed filtering of original wfdata
|
||||
except ValueError as e:
|
||||
self.qmb = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Icon.Information,
|
||||
'Denied',
|
||||
@@ -2535,8 +2582,8 @@ class PickDlg(QDialog):
|
||||
snr = []
|
||||
noiselevels = {}
|
||||
# determine SNR and noiselevel
|
||||
for trace in data.traces:
|
||||
st = data.select(channel=trace.stats.channel)
|
||||
for trace in wfdata.traces:
|
||||
st = wfdata.select(channel=trace.stats.channel)
|
||||
stime_diff = trace.stats.starttime - stime
|
||||
result = getSNR(st, (noise_win, gap_win, signal_win), ini_pick - stime_diff)
|
||||
snr.append(result[0])
|
||||
@@ -2547,23 +2594,25 @@ class PickDlg(QDialog):
|
||||
noiselevel = nfac
|
||||
noiselevels[trace.stats.channel] = noiselevel
|
||||
|
||||
# prepare plotting of data
|
||||
for trace in data:
|
||||
t = prepTimeAxis(trace.stats.starttime - stime, trace)
|
||||
inoise = getnoisewin(t, ini_pick, noise_win, gap_win)
|
||||
trace = demeanTrace(trace, inoise)
|
||||
# upscale trace data in a way that each trace is vertically zoomed to noiselevel*factor
|
||||
channel = trace.stats.channel
|
||||
noiselevel = noiselevels[channel]
|
||||
noiseScaleFactor = self.calcNoiseScaleFactor(noiselevel, zoomfactor=5.)
|
||||
trace.data *= noiseScaleFactor
|
||||
noiselevels[channel] *= noiseScaleFactor
|
||||
# prepare plotting of wfdata
|
||||
for wfd in [wfdata, wfdata_comp]:
|
||||
if wfd:
|
||||
for trace in wfd:
|
||||
t = prepTimeAxis(trace.stats.starttime - stime, trace)
|
||||
inoise = getnoisewin(t, ini_pick, noise_win, gap_win)
|
||||
trace = demeanTrace(trace, inoise)
|
||||
# upscale trace wfdata in a way that each trace is vertically zoomed to noiselevel*factor
|
||||
channel = trace.stats.channel
|
||||
noiselevel = noiselevels[channel]
|
||||
noiseScaleFactor = self.calcNoiseScaleFactor(noiselevel, zoomfactor=5.)
|
||||
trace.data *= noiseScaleFactor
|
||||
noiselevels[channel] *= noiseScaleFactor
|
||||
|
||||
mean_snr = np.mean(snr)
|
||||
x_res = getResolutionWindow(mean_snr, parameter.get('extent'))
|
||||
|
||||
xlims = [ini_pick - x_res, ini_pick + x_res]
|
||||
ylims = list(np.array([-.5, .5]) + [0, len(data) - 1])
|
||||
ylims = list(np.array([-.5, .5]) + [0, len(wfdata) - 1])
|
||||
|
||||
title = self.getStation() + ' picking mode'
|
||||
title += ' | SNR: {}'.format(mean_snr)
|
||||
@@ -2571,9 +2620,10 @@ class PickDlg(QDialog):
|
||||
filtops_str = transformFilteroptions2String(filteroptions)
|
||||
title += ' | Filteroptions: {}'.format(filtops_str)
|
||||
|
||||
plot_additional = bool(self.compareChannel.currentText())
|
||||
additional_channel = self.compareChannel.currentText()
|
||||
self.multicompfig.plotWFData(wfdata=data,
|
||||
plot_additional = bool(self.referenceChannel.currentText())
|
||||
additional_channel = self.referenceChannel.currentText()
|
||||
self.multicompfig.plotWFData(wfdata=wfdata,
|
||||
wfdata_compare=wfdata_comp,
|
||||
title=title,
|
||||
zoomx=xlims,
|
||||
zoomy=ylims,
|
||||
@@ -2654,7 +2704,7 @@ class PickDlg(QDialog):
|
||||
minFMSNR = parameter.get('minFMSNR')
|
||||
quality = get_quality_class(spe, parameter.get('timeerrorsP'))
|
||||
if quality <= minFMweight and snr >= minFMSNR:
|
||||
FM = fmpicker(self.getWFData().select(channel=channel), wfdata, parameter.get('fmpickwin'),
|
||||
FM = fmpicker(self.getWFData().select(channel=channel).copy(), wfdata.copy(), parameter.get('fmpickwin'),
|
||||
pick - stime_diff)
|
||||
|
||||
# save pick times for actual phase
|
||||
@@ -2964,7 +3014,8 @@ class PickDlg(QDialog):
|
||||
self.cur_xlim = self.multicompfig.axes[0].get_xlim()
|
||||
self.cur_ylim = self.multicompfig.axes[0].get_ylim()
|
||||
# self.multicompfig.updateCurrentLimits()
|
||||
data = self.getWFData().copy()
|
||||
wfdata = self.getWFData().copy()
|
||||
wfdata_comp = self.getWFDataComp().copy()
|
||||
title = self.getStation()
|
||||
if filter:
|
||||
filtoptions = None
|
||||
@@ -2972,19 +3023,22 @@ class PickDlg(QDialog):
|
||||
filtoptions = self.getFilterOptions(self.getPhaseID(phase), gui_filter=True).parseFilterOptions()
|
||||
|
||||
if filtoptions is not None:
|
||||
data.detrend('linear')
|
||||
data.taper(0.02, type='cosine')
|
||||
data.filter(**filtoptions)
|
||||
for wfd in [wfdata, wfdata_comp]:
|
||||
if wfd:
|
||||
wfd.detrend('linear')
|
||||
wfd.taper(0.02, type='cosine')
|
||||
wfd.filter(**filtoptions)
|
||||
filtops_str = transformFilteroptions2String(filtoptions)
|
||||
title += ' | Filteroptions: {}'.format(filtops_str)
|
||||
|
||||
if self.wftype is not None:
|
||||
title += ' | ({})'.format(self.wftype)
|
||||
|
||||
plot_additional = bool(self.compareChannel.currentText())
|
||||
additional_channel = self.compareChannel.currentText()
|
||||
plot_additional = bool(self.referenceChannel.currentText())
|
||||
additional_channel = self.referenceChannel.currentText()
|
||||
scale_channel = self.scaleChannel.currentText()
|
||||
self.multicompfig.plotWFData(wfdata=data, title=title,
|
||||
self.multicompfig.plotWFData(wfdata=wfdata, wfdata_compare=wfdata_comp,
|
||||
title=title,
|
||||
zoomx=self.getXLims(),
|
||||
zoomy=self.getYLims(),
|
||||
plot_additional=plot_additional,
|
||||
@@ -3026,7 +3080,7 @@ class PickDlg(QDialog):
|
||||
@staticmethod
|
||||
def getChannelSettingsP(channel):
|
||||
settings = QSettings()
|
||||
rval = get_Bool(settings.value('p_channel_{}'.format(channel)))
|
||||
rval = get_bool(settings.value('p_channel_{}'.format(channel)))
|
||||
compclass = SetChannelComponents.from_qsettings(settings)
|
||||
components = ['Z']
|
||||
for component in components[:]:
|
||||
@@ -3041,7 +3095,7 @@ class PickDlg(QDialog):
|
||||
@staticmethod
|
||||
def getChannelSettingsS(channel):
|
||||
settings = QSettings()
|
||||
rval = get_Bool(settings.value('s_channel_{}'.format(channel)))
|
||||
rval = get_bool(settings.value('s_channel_{}'.format(channel)))
|
||||
compclass = SetChannelComponents.from_qsettings(settings)
|
||||
components = ['N', 'E']
|
||||
for component in components[:]:
|
||||
@@ -3057,6 +3111,9 @@ class PickDlg(QDialog):
|
||||
self.resetZoom()
|
||||
self.refreshPlot()
|
||||
|
||||
def switchCompData(self):
|
||||
self.showCompData = self.compareCB.isChecked()
|
||||
|
||||
def refreshPlot(self):
|
||||
if self.autoFilterAction.isChecked():
|
||||
self.filterActionP.setChecked(False)
|
||||
@@ -3161,7 +3218,6 @@ class CanvasWidget(QWidget):
|
||||
class MultiEventWidget(QWidget):
|
||||
start = Signal()
|
||||
'''
|
||||
|
||||
'''
|
||||
|
||||
def __init__(self, options=None, parent=None, windowflag=Qt.Window):
|
||||
@@ -3438,7 +3494,6 @@ class TuneAutopicker(QWidget):
|
||||
update = QtCore.Signal(str)
|
||||
'''
|
||||
QWidget used to modifiy and test picking parameters for autopicking algorithm.
|
||||
|
||||
:param: parent
|
||||
:type: PyLoT Mainwindow
|
||||
'''
|
||||
@@ -3614,14 +3669,14 @@ class TuneAutopicker(QWidget):
|
||||
self.listWidget.scrollToBottom()
|
||||
|
||||
def get_current_event(self):
|
||||
path = self.eventBox.currentText()
|
||||
path = self.get_current_event_fp()
|
||||
return self.parent().project.getEventFromPath(path)
|
||||
|
||||
def get_current_event_name(self):
|
||||
return self.eventBox.currentText().split('/')[-1].split('*')[0]
|
||||
return self.eventBox.currentText().split('/')[-1].rstrip('*')
|
||||
|
||||
def get_current_event_fp(self):
|
||||
return self.eventBox.currentText().split('*')[0]
|
||||
return self.eventBox.currentText().rstrip('*')
|
||||
|
||||
def get_current_event_picks(self, station):
|
||||
event = self.get_current_event()
|
||||
@@ -3669,11 +3724,13 @@ class TuneAutopicker(QWidget):
|
||||
location = None
|
||||
|
||||
wfdata = self.data.getWFData()
|
||||
wfdata_comp = self.data.getWFDataComp()
|
||||
metadata = self.parent().metadata
|
||||
event = self.get_current_event()
|
||||
filteroptions = self.parent().filteroptions
|
||||
wftype = self.wftype if self.obspy_dmt else ''
|
||||
self.pickDlg = PickDlg(self.parent(), data=wfdata.select(station=station).copy(),
|
||||
data_comp=wfdata_comp.select(station=station).copy(),
|
||||
station=station, network=network,
|
||||
location=location, parameter=self.parameter,
|
||||
picks=self.get_current_event_picks(station),
|
||||
@@ -3757,7 +3814,7 @@ class TuneAutopicker(QWidget):
|
||||
self.plot_manual_pick_to_ax(ax=ax, picks=picks, phase='S',
|
||||
starttime=starttime, quality=qualitySpick)
|
||||
for canvas in self.parent().canvas_dict.values():
|
||||
canvas.draw()
|
||||
canvas.draw_idle()
|
||||
|
||||
def plot_manual_pick_to_ax(self, ax, picks, phase, starttime, quality):
|
||||
mpp = picks[phase]['mpp'] - starttime
|
||||
@@ -3959,10 +4016,8 @@ class PylotParaBox(QtWidgets.QWidget):
|
||||
def __init__(self, parameter, parent=None, windowflag=Qt.Window):
|
||||
'''
|
||||
Generate Widget containing parameters for PyLoT.
|
||||
|
||||
:param: parameter
|
||||
:type: PylotParameter (object)
|
||||
|
||||
'''
|
||||
QtWidgets.QWidget.__init__(self, parent, windowflag)
|
||||
self.parameter = parameter
|
||||
@@ -5199,7 +5254,7 @@ class FilterOptionsDialog(QDialog):
|
||||
'S': QtWidgets.QGroupBox('S Filter')}
|
||||
|
||||
settings = QSettings()
|
||||
overwriteFilter = get_Bool(settings.value('useGuiFilter'))
|
||||
overwriteFilter = get_bool(settings.value('useGuiFilter'))
|
||||
|
||||
self.overwriteFilterCheckbox = QCheckBox('Overwrite filteroptions')
|
||||
self.overwriteFilterCheckbox.setToolTip('Overwrite filter settings for refined pick with GUI settings')
|
||||
@@ -5561,6 +5616,251 @@ class HelpForm(QDialog):
|
||||
self.pageLabel.setText(self.webBrowser.title())
|
||||
|
||||
|
||||
class PickQualitiesFromXml(QWidget):
|
||||
"""
|
||||
PyLoT widget PickQualitiesFromXml is a QWidget object. It is an UI that enables the user
|
||||
to create a plot showing the pick qualities in the event selected inside the QComboBox created
|
||||
by this Widget. The user can also choose to select all Events.
|
||||
The plot is being shown by a FigureCanvas from matlplotlib.
|
||||
"""
|
||||
|
||||
def __init__(self, parent=None, figure=Figure(), path="", inputVar=None):
|
||||
super(PickQualitiesFromXml, self).__init__(parent)
|
||||
|
||||
self.fig = figure
|
||||
self.chooseBox = QComboBox()
|
||||
self.path = path
|
||||
self.inputs = inputVar
|
||||
self.setupUi()
|
||||
|
||||
def setupUi(self):
|
||||
self.setWindowTitle("Get pick qualities from xml files")
|
||||
self.main_layout = QtWidgets.QVBoxLayout()
|
||||
self.figureC = FigureCanvas(self.fig)
|
||||
self.chooseBox = self.createComboBox()
|
||||
if self.chooseBox:
|
||||
self.main_layout.addWidget(self.chooseBox)
|
||||
self.main_layout.addWidget(self.figureC)
|
||||
self.setLayout(self.main_layout)
|
||||
|
||||
def showUI(self):
|
||||
self.show()
|
||||
|
||||
# Creates a QComboBox and adds all events in the current folder as options. Also gives the option to choose all events
|
||||
def createComboBox(self):
|
||||
self.chooseBox.addItems(glob.glob(os.path.join(os.path.dirname(self.path) + "/*/", '*.xml')))
|
||||
self.chooseBox.addItem("All")
|
||||
self.chooseBox.currentIndexChanged.connect(self.selectionChanged)
|
||||
self.chooseBox.setCurrentIndex(self.chooseBox.count() - 1)
|
||||
return self.chooseBox
|
||||
|
||||
# Function that gets called when the user changes the current selection in the QComboBox. Redraws the plot with the new data
|
||||
def selectionChanged(self):
|
||||
self.figureC.setParent(None)
|
||||
if self.chooseBox.currentIndex() == self.chooseBox.count() - 1:
|
||||
(_, _, plot) = getQualitiesfromxml(self.path, self.inputs.get('timeerrorsP'),
|
||||
self.inputs.get('timeerrorsS'), plotflag=1)
|
||||
self.figureC = FigureCanvas(plot)
|
||||
else:
|
||||
(_, _, plot) = getQualitiesfromxml(self.path, self.inputs.get('timeerrorsP'),
|
||||
self.inputs.get('timeerrorsS'), plotflag=1,
|
||||
xmlnames=[self.chooseBox.currentText()])
|
||||
self.figureC = FigureCanvas(plot)
|
||||
self.figureC.draw()
|
||||
self.main_layout.addWidget(self.figureC)
|
||||
self.setLayout(self.main_layout)
|
||||
|
||||
|
||||
class SourceSpecWindow(QWidget):
|
||||
def __init__(self, parent=None, figure=Figure()):
|
||||
super(SourceSpecWindow, self).__init__(parent)
|
||||
self.main_layout = QVBoxLayout()
|
||||
self.setWindowTitle("Display source spectrum from selected trace")
|
||||
self.fig = figure
|
||||
|
||||
def setupUi(self):
|
||||
self.figureC = FigureCanvas(self.fig)
|
||||
self.main_layout.addWidget(self.figureC)
|
||||
self.setLayout(self.main_layout)
|
||||
|
||||
|
||||
class ChooseWaveFormWindow(QWidget):
|
||||
def __init__(self, parent=None, WaveForms=[], traces=[], stream=None, chooseB=False):
|
||||
super(ChooseWaveFormWindow, self).__init__(parent)
|
||||
self.main_layout = QVBoxLayout()
|
||||
self.setWindowTitle("Choose trace to display source spectrum")
|
||||
self.wFs = WaveForms
|
||||
self.chooseBoxTraces = QComboBox()
|
||||
self.chooseBoxComponent = QComboBox()
|
||||
self.submitButton = QPushButton(text='test')
|
||||
|
||||
self.chooseB = chooseB
|
||||
|
||||
self.verticalButton = QPushButton(text='Z')
|
||||
self.northButton = QPushButton(text='N')
|
||||
self.eastButton = QPushButton(text='E')
|
||||
self.component = ''
|
||||
|
||||
self.traces = traces
|
||||
self.stream = stream
|
||||
self.setupUI()
|
||||
self.currentSpectro = Figure()
|
||||
|
||||
def setupUI(self):
|
||||
self.submitButton.clicked.connect(self.submit)
|
||||
self.createComboBoxTraces()
|
||||
self.main_layout.addWidget(self.chooseBoxTraces)
|
||||
|
||||
if self.chooseB:
|
||||
self.createComboBoxComponent()
|
||||
self.main_layout.addWidget(self.submitButton)
|
||||
self.main_layout.addWidget(self.chooseBoxComponent)
|
||||
else:
|
||||
self.createButtonsComponent()
|
||||
|
||||
self.setLayout(self.main_layout)
|
||||
|
||||
def submit(self):
|
||||
matplotlib.pyplot.close(self.currentSpectro)
|
||||
t = self.chooseBoxTraces.currentText() + " " + self.chooseBoxComponent.currentText()
|
||||
#self.currentSpectro = self.traces[
|
||||
# self.chooseBoxTraces.currentText()[3:]][self.chooseBoxComponent.currentText()].spectrogram(show=False, title=t)
|
||||
#self.currentSpectro.show()
|
||||
applyFFT()
|
||||
|
||||
def applyFFT(self, trace):
|
||||
tra = self.traces[self.chooseBoxTraces.currentText()[3:]]['Z']
|
||||
transformed = abs(np.fft.rfft(tra.data))
|
||||
print ( transformed )
|
||||
matplotlib.pyplot.plot ( transformed )
|
||||
matplotlib.pyplot.show()
|
||||
|
||||
def applyFFTs(self, tra):
|
||||
transformed = abs(np.fft.rfft(tra.data))
|
||||
print ( transformed )
|
||||
matplotlib.pyplot.plot ( transformed )
|
||||
matplotlib.pyplot.show()
|
||||
|
||||
def submitN(self):
|
||||
matplotlib.pyplot.close(self.currentSpectro)
|
||||
t = self.chooseBoxTraces.currentText() + " " + self.chooseBoxComponent.currentText()
|
||||
self.currentSpectro = self.traces[
|
||||
self.chooseBoxTraces.currentText()[3:]]['N'].spectrogram(show=False, title=t)
|
||||
self.currentSpectro.show()
|
||||
|
||||
def submitE(self):
|
||||
matplotlib.pyplot.close(self.currentSpectro)
|
||||
t = self.chooseBoxTraces.currentText() + " " + self.chooseBoxComponent.currentText()
|
||||
self.currentSpectro = self.traces[
|
||||
self.chooseBoxTraces.currentText()[3:]]['E'].spectrogram(show=False, title=t)
|
||||
self.currentSpectro.show()
|
||||
|
||||
# Creates a QComboBox and adds all traces provided
|
||||
def createComboBoxTraces(self):
|
||||
if len(self.wFs) <= 0:
|
||||
raise 'No traces provided'
|
||||
self.chooseBoxTraces.addItems(self.wFs)
|
||||
self.chooseBoxTraces.currentIndexChanged.connect(self.selectionChanged)
|
||||
self.chooseBoxTraces.setCurrentIndex(0)
|
||||
return self.chooseBoxTraces
|
||||
|
||||
def createButtonsComponent(self):
|
||||
self.northButton.clicked.connect(self.submitN)
|
||||
self.eastButton.clicked.connect(self.submitE)
|
||||
self.verticalButton.clicked.connect(self.submitZ)
|
||||
|
||||
self.main_layout.addWidget(self.verticalButton)
|
||||
self.main_layout.addWidget(self.northButton)
|
||||
self.main_layout.addWidget(self.eastButton)
|
||||
|
||||
def createComboBoxComponent(self):
|
||||
self.chooseBoxComponent.addItems(['Z', 'N', 'E'])
|
||||
|
||||
# Function that gets called when the user changes the current selection in the QComboBox.
|
||||
def selectionChanged(self):
|
||||
pass
|
||||
|
||||
|
||||
class SpectrogramTab(QWidget):
|
||||
def __init__(self, traces, wfdata, parent=None):
|
||||
super(SpectrogramTab, self).__init__(parent)
|
||||
self.setupUi()
|
||||
self.traces = traces
|
||||
self.wfdata = wfdata
|
||||
|
||||
def setupUi(self):
|
||||
pass
|
||||
def makeSpecFig(self, direction = 'Z', height = 0, width = 0, parent = None):
|
||||
|
||||
i = 0
|
||||
grams = []
|
||||
figure, axis = matplotlib.pyplot.subplots(len(self.traces), sharex=True)
|
||||
|
||||
start, end = full_range(self.wfdata)
|
||||
|
||||
if height != 0 and width != 0:
|
||||
figure.figsize = (width, height)
|
||||
figure.set_figwidth = width
|
||||
figure.set_figheight = height
|
||||
|
||||
#figure.tight_layout()
|
||||
|
||||
for t in self.traces:
|
||||
tra = self.traces[t][direction]
|
||||
#print(start, end)
|
||||
|
||||
# Set Title
|
||||
if i == 0:
|
||||
if direction == 'Z':
|
||||
figure.suptitle("section: vertical components")
|
||||
elif direction == 'E':
|
||||
figure.suptitle("section: east-west components")
|
||||
elif direction == 'N':
|
||||
figure.suptitle("section: north-south components")
|
||||
axis[i].vlines(0, axis[i].get_ylim()[0], axis[i].get_ylim()[1],
|
||||
colors='m', linestyles='dashed',
|
||||
linewidth=2)
|
||||
|
||||
# Different axis settings for visual improvements
|
||||
# axis[i].set_xlim(left=0, right=end - start)
|
||||
# axis[i].spines['top'].set_visible(False)
|
||||
# axis[i].spines['right'].set_visible(False)
|
||||
# # axis[i].spines['left'].set_visible(False)
|
||||
|
||||
# axis[i].tick_params(axis='x', which='both', bottom=False, top=False, labelbottom=False)
|
||||
# if not (len(self.traces) == i - 1):
|
||||
# axis[i].spines['bottom'].set_visible(False)
|
||||
# axis[i].set_yticks([])
|
||||
# axis[i].set_ylabel(t, loc='center', rotation='horizontal')
|
||||
|
||||
#ax.axhline(n, color="0.5", lw=0.5)
|
||||
|
||||
|
||||
grams.append(tra.spectrogram(show=False, axes=axis[i]))
|
||||
i+=1
|
||||
|
||||
#figure.setXLims([0, end - start])
|
||||
figure.set_tight_layout(True)
|
||||
fC = FigureCanvas(figure)
|
||||
return fC
|
||||
|
||||
#for t in self.traces:
|
||||
# tra = self.traces[t]['Z']
|
||||
# transformed = abs(np.fft.rfft(tra.data))
|
||||
# axis[i].plot(transformed, label=t)
|
||||
# # axis[i].tick_params(labelbottom=False)
|
||||
# axis[i].spines['top'].set_visible(False)
|
||||
# axis[i].spines['right'].set_visible(False)
|
||||
# axis[i].spines['left'].set_visible(False)
|
||||
# if not (len(self.traces) == i - 1):
|
||||
# axis[i].spines['bottom'].set_visible(False)
|
||||
# axis[i].set_yticks([])
|
||||
# axis[i].set_ylabel(t, loc='center', rotation='horizontal')
|
||||
# # axis[i].axis('off')
|
||||
# i += 1
|
||||
# # self.applyFFTs(t)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
|
||||
|
||||
Reference in New Issue
Block a user