Compare commits
18 Commits
b5ba62e86f
...
341db86861
Author | SHA1 | Date | |
---|---|---|---|
341db86861 | |||
bfec58cc24 | |||
172786dc6d | |||
a9784d33e5 | |||
21453159b7 | |||
f40d22af33 | |||
01fea084d5 | |||
16f6e2d1fd | |||
49c747b638 | |||
f8f4e6789c | |||
08c2d7556f | |||
7d77cb0b2f | |||
6f70b2c0e2 | |||
8f1ab87045 | |||
5351043493 | |||
dccbaa357a | |||
37c8858096 | |||
f93499da7d |
179
PyLoT.py
179
PyLoT.py
@ -190,6 +190,58 @@ class MainWindow(QMainWindow):
|
||||
settings.setValue("output/Format", outformat)
|
||||
settings.sync()
|
||||
|
||||
# track deleted picks for logging
|
||||
self.deleted_picks = {}
|
||||
|
||||
# headers for event table
|
||||
self.table_headers = ['', 'Event', 'Time', 'Lat', 'Lon', 'Depth', 'Ml', 'Mw', '[N] MP', '[N] AP', 'Tuning Set',
|
||||
'Test Set', 'Notes']
|
||||
|
||||
while True:
|
||||
try:
|
||||
if settings.value("user/FullName", None) is None:
|
||||
fulluser = QInputDialog.getText(self, "Enter Name:", "Full name")
|
||||
settings.setValue("user/FullName", fulluser)
|
||||
settings.setValue("user/Login", getLogin())
|
||||
if settings.value("agency_id", None) is None:
|
||||
agency = QInputDialog.getText(self,
|
||||
"Enter authority/institution name:",
|
||||
"Authority")
|
||||
settings.setValue("agency_id", agency)
|
||||
structure_setting = settings.value("data/Structure", "PILOT")
|
||||
if not structure_setting:
|
||||
structure_setting = 'PILOT'
|
||||
self.dataStructure = DATASTRUCTURE[structure_setting]()
|
||||
self.seismicPhase = str(settings.value("phase", "P"))
|
||||
if settings.value("data/dataRoot", None) is None:
|
||||
dirname = QFileDialog().getExistingDirectory(
|
||||
caption='Choose data root ...')
|
||||
settings.setValue("data/dataRoot", dirname)
|
||||
if settings.value('useGuiFilter') is None:
|
||||
settings.setValue('useGuiFilter', False)
|
||||
if settings.value('output/Format', None) is None:
|
||||
outformat = QInputDialog.getText(self,
|
||||
"Enter output format (*.xml, *.cnv, *.obs, *_focmec.in, *.pha):",
|
||||
"Format")
|
||||
settings.setValue("output/Format", outformat)
|
||||
if settings.value('autoFilter', None) is None:
|
||||
settings.setValue('autoFilter', True)
|
||||
settings.sync()
|
||||
break
|
||||
except Exception as e:
|
||||
qmb = QMessageBox(self, icon=QMessageBox.Question,
|
||||
text='Could not init application settings: {}.'
|
||||
'Do you want to reset application settings?'.format(e),
|
||||
windowTitle='PyLoT - Init QSettings warning')
|
||||
qmb.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
|
||||
qmb.setDefaultButton(QMessageBox.No)
|
||||
ret = qmb.exec_()
|
||||
if ret == qmb.Yes:
|
||||
settings.clear()
|
||||
else:
|
||||
sys.exit()
|
||||
print('Settings cleared!')
|
||||
|
||||
# setup UI
|
||||
self.setupUi()
|
||||
|
||||
@ -1114,6 +1166,34 @@ class MainWindow(QMainWindow):
|
||||
self.refreshEvents()
|
||||
tabindex = self.tabs.currentIndex()
|
||||
|
||||
def user_modify_path(self, reason=''):
|
||||
dialog = QtGui.QInputDialog(parent=self)
|
||||
new_path, executed = dialog.getText(self, 'Change Project rootpath',
|
||||
'{}Rename project path {}:'.format(reason, self.project.rootpath))
|
||||
return new_path, executed
|
||||
|
||||
def data_check(self):
|
||||
paths_exist = [os.path.exists(event.path) for event in self.project.eventlist]
|
||||
if all(paths_exist):
|
||||
return True
|
||||
elif not any(paths_exist):
|
||||
return False
|
||||
else:
|
||||
info_str = ''
|
||||
for event, path_exists in zip(self.project.eventlist, paths_exist):
|
||||
if not path_exists:
|
||||
info_str += '\n{} exists: {}'.format(event.path, path_exists)
|
||||
print('Unable to find certain event paths:{}'.format(info_str))
|
||||
return True
|
||||
|
||||
def modify_project_path(self, new_rootpath):
|
||||
self.project.rootpath = new_rootpath
|
||||
for event in self.project.eventlist:
|
||||
event.rootpath = new_rootpath
|
||||
event.path = os.path.join(event.rootpath, event.datapath, event.database, event.pylot_id)
|
||||
event.path = event.path.replace('\\', '/')
|
||||
event.path = event.path.replace('//', '/')
|
||||
|
||||
def fill_eventbox(self, event=None, eventBox=None, select_events='all'):
|
||||
'''
|
||||
(Re)fill the selected eventBox (type = QtGui.QComboBox).
|
||||
@ -1171,14 +1251,33 @@ class MainWindow(QMainWindow):
|
||||
event_ref = event.isRefEvent()
|
||||
event_test = event.isTestEvent()
|
||||
|
||||
time = lat = lon = depth = mag = None
|
||||
if len(event.origins) == 1:
|
||||
origin = event.origins[0]
|
||||
time = origin.time + 0 # add 0 because there was an exception for time = 0s
|
||||
lat = origin.latitude
|
||||
lon = origin.longitude
|
||||
depth = origin.depth
|
||||
if len(event.magnitudes) == 1:
|
||||
magnitude = event.magnitudes[0]
|
||||
mag = magnitude.mag
|
||||
|
||||
# text = '{path:{plen}} | manual: [{p:3d}] | auto: [{a:3d}]'
|
||||
# text = text.format(path=event_path,
|
||||
# plen=plmax,
|
||||
# p=event_npicks,
|
||||
# a=event_nautopicks)
|
||||
|
||||
item_path = QtGui.QStandardItem('{path:{plen}}'.format(path=event_path, plen=plmax))
|
||||
item_nmp = QtGui.QStandardItem(str(ma_count['manual']))
|
||||
event_str = '{path:{plen}}'.format(path=event_path, plen=plmax)
|
||||
if event.dirty:
|
||||
event_str += '*'
|
||||
item_path = QtGui.QStandardItem(event_str)
|
||||
item_time = QtGui.QStandardItem('{}'.format(time))
|
||||
item_lat = QtGui.QStandardItem('{}'.format(lat))
|
||||
item_lon = QtGui.QStandardItem('{}'.format(lon))
|
||||
item_depth = QtGui.QStandardItem('{}'.format(depth))
|
||||
item_mag = QtGui.QStandardItem('{}'.format(mag))
|
||||
item_nmp = QtGui.QStandardItem('{}({})'.format(ma_count['manual'], ma_count_total['manual']))
|
||||
item_nmp.setIcon(self.manupicksicon_small)
|
||||
item_nap = QtGui.QStandardItem(str(ma_count['auto']))
|
||||
item_nap.setIcon(self.autopicksicon_small)
|
||||
@ -1203,8 +1302,11 @@ class MainWindow(QMainWindow):
|
||||
# item.setFont(font)
|
||||
# item2.setForeground(QtGui.QColor('black'))
|
||||
# item2.setFont(font)
|
||||
itemlist = [item_path, item_nmp, item_nap, item_ref, item_test, item_notes]
|
||||
if event_test and select_events == 'ref':
|
||||
itemlist = [item_path, item_time, item_lat, item_lon, item_depth,
|
||||
item_mag, item_nmp, item_nap, item_ref, item_test, item_notes]
|
||||
for item in itemlist:
|
||||
item.setTextAlignment(Qt.AlignCenter)
|
||||
if event_test and select_events == 'ref' or self.isEmpty(event_path):
|
||||
for item in itemlist:
|
||||
item.setEnabled(False)
|
||||
model.appendRow(itemlist)
|
||||
@ -1236,7 +1338,7 @@ class MainWindow(QMainWindow):
|
||||
self.set_fname(self.get_data().getEventFileName(), type)
|
||||
return self.get_fnames(type)
|
||||
|
||||
def saveData(self, event=None, directory=None, outformats=['.xml', '.cnv', '.obs']):
|
||||
def saveData(self, event=None, directory=None, outformats=['.xml', '.cnv', '.obs', '.focmec', '.pha']):
|
||||
'''
|
||||
Save event data to directory with specified output formats.
|
||||
:param event: PyLoT Event, if not set current event will be used
|
||||
@ -1966,8 +2068,40 @@ class MainWindow(QMainWindow):
|
||||
|
||||
def pickDialog(self, wfID, nextStation=False):
|
||||
station = self.getStationName(wfID)
|
||||
network = self.getNetworkName(wfID)
|
||||
if not station:
|
||||
location = self.getLocationName(wfID)
|
||||
seed_id = self.getTraceID(wfID)
|
||||
if button == 1:
|
||||
self.pickDialog(wfID, seed_id)
|
||||
elif button == 4:
|
||||
self.toggle_station_color(wfID, network, station, location)
|
||||
|
||||
def toggle_station_color(self, wfID, network, station, location):
|
||||
black_pen = pg.mkPen((0, 0, 0))
|
||||
red_pen = pg.mkPen((200, 50, 50))
|
||||
line_item = self.dataPlot.plotWidget.getPlotItem().listDataItems()[wfID - 1]
|
||||
current_pen = line_item.opts['pen']
|
||||
nsl = '{}.{}.{}'.format(network, station, location)
|
||||
if current_pen == black_pen:
|
||||
line_item.setPen(red_pen)
|
||||
if not nsl in self.stations_highlighted:
|
||||
self.stations_highlighted.append(nsl)
|
||||
else:
|
||||
line_item.setPen(black_pen)
|
||||
if nsl in self.stations_highlighted:
|
||||
self.stations_highlighted.pop(self.stations_highlighted.index(nsl))
|
||||
|
||||
def highlight_stations(self):
|
||||
for wfID, value in self.getPlotWidget().getPlotDict().items():
|
||||
station, channel, location, network = value.split('.')
|
||||
nsl = '{}.{}.{}'.format(network, station, location)
|
||||
if nsl in self.stations_highlighted:
|
||||
self.toggle_station_color(wfID, network, station, location)
|
||||
|
||||
def pickDialog(self, wfID, seed_id=None):
|
||||
if not seed_id:
|
||||
seed_id = self.getTraceID(wfID)
|
||||
network, station, location = seed_id.split('.')[:3]
|
||||
if not station or not network:
|
||||
return
|
||||
self.update_status('picking on station {0}'.format(station))
|
||||
data = self.get_data().getWFData()
|
||||
@ -2682,7 +2816,7 @@ class MainWindow(QMainWindow):
|
||||
item_lon = QtGui.QTableWidgetItem()
|
||||
item_depth = QtGui.QTableWidgetItem()
|
||||
item_mag = QtGui.QTableWidgetItem()
|
||||
item_nmp = QtGui.QTableWidgetItem(str(ma_count['manual']))
|
||||
item_nmp = QtGui.QTableWidgetItem('{}({})'.format(ma_count['manual'], ma_count_total['manual']))
|
||||
item_nmp.setIcon(self.manupicksicon_small)
|
||||
item_nap = QtGui.QTableWidgetItem(str(ma_count['auto']))
|
||||
item_nap.setIcon(self.autopicksicon_small)
|
||||
@ -2703,8 +2837,12 @@ class MainWindow(QMainWindow):
|
||||
item_depth.setText(str(origin.depth))
|
||||
if hasattr(event, 'magnitudes'):
|
||||
if event.magnitudes:
|
||||
magnitude = event.magnitudes[0]
|
||||
item_mag.setText(str(magnitude.mag))
|
||||
moment_magnitude = event.magnitudes[0]
|
||||
moment_magnitude.mag = '%4.1f' % moment_magnitude.mag
|
||||
local_magnitude = event.magnitudes[1]
|
||||
local_magnitude.mag = '%4.1f' % local_magnitude.mag
|
||||
item_momentmag.setText(str(moment_magnitude.mag))
|
||||
item_localmag.setText(str(local_magnitude.mag))
|
||||
item_notes.setText(event.notes)
|
||||
|
||||
set_enabled(item_path, True, False)
|
||||
@ -2727,9 +2865,9 @@ class MainWindow(QMainWindow):
|
||||
else:
|
||||
item_test.setCheckState(QtCore.Qt.Unchecked)
|
||||
|
||||
column = [item_delete, item_path, item_time, item_lat, item_lon, item_depth, item_mag,
|
||||
row = [item_delete, item_path, item_time, item_lat, item_lon, item_depth, item_mag,
|
||||
item_nmp, item_nap, item_ref, item_test, item_notes]
|
||||
self.project._table.append(column)
|
||||
self.project._table.append(row)
|
||||
|
||||
for r_index, row in enumerate(self.project._table):
|
||||
for c_index, item in enumerate(row):
|
||||
@ -3131,13 +3269,16 @@ class Project(object):
|
||||
datapaths.append(event.datapath)
|
||||
for datapath in datapaths:
|
||||
datapath = os.path.join(self.rootpath, datapath)
|
||||
for filename in os.listdir(datapath):
|
||||
filename = os.path.join(datapath, filename)
|
||||
if os.path.isfile(filename) and filename.endswith(fext):
|
||||
try:
|
||||
self.read_eventfile_info(filename)
|
||||
except Exception as e:
|
||||
print('Failed on reading eventfile info from file {}: {}'.format(filename, e))
|
||||
if os.path.isdir(datapath):
|
||||
for filename in os.listdir(datapath):
|
||||
filename = os.path.join(datapath, filename)
|
||||
if os.path.isfile(filename) and filename.endswith(fext):
|
||||
try:
|
||||
self.read_eventfile_info(filename)
|
||||
except Exception as e:
|
||||
print('Failed on reading eventfile info from file {}: {}'.format(filename, e))
|
||||
else:
|
||||
print("Directory %s does not exist!" % datapath)
|
||||
|
||||
def getPaths(self):
|
||||
'''
|
||||
|
@ -166,7 +166,7 @@ def installPyLoT(verbosity=None):
|
||||
if verbosity > 1:
|
||||
print('copying input files into destination folder ...')
|
||||
ans = input('please specify scope of interest '
|
||||
'([0]=local, 1=regional, 2=global) :') or 0
|
||||
'([0]=local, 1=regional, 2=global, 3=active) :') or 0
|
||||
if not isinstance(ans, int):
|
||||
ans = int(ans)
|
||||
if ans == 0:
|
||||
@ -175,6 +175,8 @@ def installPyLoT(verbosity=None):
|
||||
ans = 'regional'
|
||||
elif ans == 2:
|
||||
ans = 'global'
|
||||
elif ans == 3:
|
||||
ans = 'active'
|
||||
link_dest = []
|
||||
for file, destination in files_to_copy.items():
|
||||
link_file = ans in file
|
||||
|
@ -522,7 +522,6 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
|
||||
|
||||
Fc = None
|
||||
w0 = None
|
||||
|
||||
zdat = select_for_phase(wfstream, "P")
|
||||
|
||||
if len(zdat) == 0:
|
||||
@ -537,7 +536,6 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
|
||||
# trim traces to common range (for rotation)
|
||||
trstart, trend = common_range(wfstream)
|
||||
wfstream.trim(trstart, trend)
|
||||
|
||||
# rotate into LQT (ray-coordindate-) system using Obspy's rotate
|
||||
# L: P-wave direction
|
||||
# Q: SV-wave direction
|
||||
@ -591,7 +589,8 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
|
||||
#n = freq * l
|
||||
# find next power of 2 of data length
|
||||
m = pow(2, np.ceil(np.log(len(xdat)) / np.log(2)))
|
||||
N = int(np.power(m, 2))
|
||||
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])
|
||||
L = (N - 1) / freq
|
||||
|
@ -366,7 +366,7 @@ class Data(object):
|
||||
except KeyError as e:
|
||||
raise KeyError('''{0} export format
|
||||
not implemented: {1}'''.format(evtformat, e))
|
||||
if fnext == '.focmec':
|
||||
if fnext == '_focmec.in':
|
||||
try:
|
||||
infile = os.path.join(os.path.expanduser('~'), '.pylot', 'pylot.in')
|
||||
print('Using default input file {}'.format(infile))
|
||||
|
@ -27,7 +27,7 @@ defaults = {'rootpath': {'type': str,
|
||||
'namestring': 'Event ID'},
|
||||
|
||||
'extent': {'type': str,
|
||||
'tooltip': 'extent of array ("local", "regional" or "global")',
|
||||
'tooltip': 'extent of array ("active", "local", "regional" or "global")',
|
||||
'value': 'local',
|
||||
'namestring': 'Array extent'},
|
||||
|
||||
|
@ -290,7 +290,16 @@ def picksdict_from_picks(evt):
|
||||
phase['channel'] = channel
|
||||
phase['network'] = network
|
||||
phase['picker'] = picker
|
||||
phase['fm'] = 'N'
|
||||
try:
|
||||
if pick.polarity == 'positive':
|
||||
phase['fm'] = 'U'
|
||||
elif pick.polarity == 'negative':
|
||||
phase['fm'] = 'D'
|
||||
else:
|
||||
phase['fm'] = 'N'
|
||||
except:
|
||||
print("No FM info available!")
|
||||
phase['fm'] = 'N'
|
||||
phase['filter_id'] = filter_id if filter_id is not None else ''
|
||||
|
||||
onsets[pick.phase_hint] = phase.copy()
|
||||
@ -350,19 +359,18 @@ def picks_from_picksdict(picks, creation_info=None):
|
||||
warnings.warn(str(e), RuntimeWarning)
|
||||
filter_id = ''
|
||||
pick.filter_id = filter_id
|
||||
|
||||
try:
|
||||
polarity = phase['fm']
|
||||
if polarity == 'U' or '+':
|
||||
polarity = picks[station][label]['fm']
|
||||
if polarity == 'U' or polarity == '+':
|
||||
pick.polarity = 'positive'
|
||||
elif polarity == 'D' or '-':
|
||||
elif polarity == 'D' or polarity == '-':
|
||||
pick.polarity = 'negative'
|
||||
else:
|
||||
pick.polarity = 'undecidable'
|
||||
except KeyError as e:
|
||||
if 'fm' in str(e): # no polarity information found for this phase
|
||||
pass
|
||||
else:
|
||||
raise e
|
||||
except:
|
||||
pick.polarity = 'undecidable'
|
||||
print("No polarity information available!")
|
||||
picks_list.append(pick)
|
||||
return picks_list
|
||||
|
||||
@ -564,7 +572,9 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
|
||||
sweight = 0 # do not use pick
|
||||
except KeyError as e:
|
||||
print(str(e) + '; no weight set during processing')
|
||||
fid.write('%s ? ? ? S %s %d%02d%02d %02d%02d %7.4f GAU 0 0 0 0 %d \n' % (key,
|
||||
Ao = arrivals[key]['S']['Ao'] # peak-to-peak amplitude
|
||||
#fid.write('%s ? ? ? S %s %d%02d%02d %02d%02d %7.4f GAU 0 0 0 0 %d \n' % (key,
|
||||
fid.write('%s ? ? ? S %s %d%02d%02d %02d%02d %7.4f GAU 0 %9.2f 0 0 %d \n' % (key,
|
||||
fm,
|
||||
year,
|
||||
month,
|
||||
@ -572,6 +582,7 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
|
||||
hh,
|
||||
mm,
|
||||
ss_ms,
|
||||
Ao,
|
||||
sweight))
|
||||
|
||||
fid.close()
|
||||
@ -832,8 +843,15 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
|
||||
print("No source origin calculated yet, thus no FOCMEC-infile creation possible!")
|
||||
return
|
||||
stime = eventsource['time']
|
||||
|
||||
# avoid printing '*' in focmec-input file
|
||||
if parameter.get('eventid') == '*' or parameter.get('eventid') is None:
|
||||
evID = 'e0000'
|
||||
else:
|
||||
evID = parameter.get('eventid')
|
||||
|
||||
# write header line including event information
|
||||
fid.write('%s %d%02d%02d%02d%02d%02.0f %7.4f %6.4f %3.1f %3.1f\n' % (parameter.get('eventID'),
|
||||
fid.write('%s %d%02d%02d%02d%02d%02.0f %7.4f %6.4f %3.1f %3.1f\n' % (evID,
|
||||
stime.year, stime.month, stime.day,
|
||||
stime.hour, stime.minute, stime.second,
|
||||
eventsource['latitude'],
|
||||
|
@ -892,7 +892,7 @@ class AutopickStation(object):
|
||||
# weight P-onset using symmetric error
|
||||
self.p_results.weight = get_quality_class(self.p_results.spe, self.pickparams["timeerrorsP"])
|
||||
if self.p_results.weight <= self.pickparams["minfmweight"] and self.p_results.snr >= self.pickparams["minFMSNR"]:
|
||||
# if SNR is low enough, try to determine first motion of onset
|
||||
# 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.iplot, self.current_figure, self.current_linecolor)
|
||||
|
@ -498,22 +498,16 @@ def getResolutionWindow(snr, extent='local'):
|
||||
2 > SNR >= 1.5 -> 10 sec LRW
|
||||
1.5 > SNR -> 15 sec VLRW
|
||||
see also Diehl et al. 2009
|
||||
|
||||
:parameter: extent, can be 'local', 'regional', 'global'
|
||||
|
||||
>>> getResolutionWindow(0.5)
|
||||
7.5
|
||||
>>> getResolutionWindow(1.8)
|
||||
5.0
|
||||
>>> getResolutionWindow(2.3)
|
||||
2.5
|
||||
>>> getResolutionWindow(4)
|
||||
1.0
|
||||
>>> getResolutionWindow(2)
|
||||
2.5
|
||||
:param snr: Signal to noise ration which decides the witdth of the resolution window
|
||||
:type snr: float
|
||||
:param extent: can be 'active', 'local', 'regional', 'global'
|
||||
:type extent: str
|
||||
:return: half width of the resolution window
|
||||
:rtype: float
|
||||
"""
|
||||
|
||||
res_wins = {
|
||||
'active': {'HRW': .02, 'MRW': .05, 'LRW': .1, 'VLRW': .15},
|
||||
'regional': {'HRW': 2., 'MRW': 5., 'LRW': 10., 'VLRW': 15.},
|
||||
'local': {'HRW': 2., 'MRW': 5., 'LRW': 10., 'VLRW': 15.},
|
||||
'global': {'HRW': 40., 'MRW': 100., 'LRW': 200., 'VLRW': 300.}
|
||||
|
@ -37,7 +37,7 @@ TIMEERROR_DEFAULTS = os.path.join(os.path.expanduser('~'),
|
||||
OUTPUTFORMATS = {'.xml': 'QUAKEML',
|
||||
'.cnv': 'CNV',
|
||||
'.obs': 'NLLOC_OBS',
|
||||
'.focmec': 'FOCMEC',
|
||||
'_focmec.in': 'FOCMEC',
|
||||
'.pha': 'HYPODD'}
|
||||
|
||||
LOCTOOLS = dict(nll=nll, hyposat=hyposat, velest=velest, hypo71=hypo71, hypodd=hypodd)
|
||||
|
@ -46,11 +46,14 @@ from pylot.core.io.inputs import FilterOptions, PylotParameter
|
||||
from pylot.core.pick.utils import getSNR, earllatepicker, getnoisewin, \
|
||||
getResolutionWindow, getQualityFromUncertainty
|
||||
from pylot.core.pick.compare import Comparison
|
||||
from pylot.core.util.defaults import OUTPUTFORMATS, FILTERDEFAULTS, \
|
||||
SetChannelComponents
|
||||
from pylot.core.util.utils import prepTimeAxis, full_range, scaleWFData, \
|
||||
demeanTrace, isSorted, findComboBoxIndex, clims, pick_linestyle_plt, pick_color_plt, \
|
||||
check4rotated, check4doubled, check4gaps, remove_underscores
|
||||
from pylot.core.pick.autopick import fmpicker
|
||||
from pylot.core.util.defaults import OUTPUTFORMATS, FILTERDEFAULTS
|
||||
from pylot.core.util.utils import prepTimeAxis, full_range, demeanTrace, isSorted, findComboBoxIndex, clims, \
|
||||
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,\
|
||||
station_id_remove_channel
|
||||
from autoPyLoT import autoPyLoT
|
||||
from pylot.core.util.thread import Thread
|
||||
|
||||
@ -1903,13 +1906,32 @@ class PickDlg(QDialog):
|
||||
pick - stime_diff, verbosity=1)
|
||||
|
||||
mpp = stime + pick
|
||||
|
||||
if epp:
|
||||
epp = stime + epp + stime_diff
|
||||
if lpp:
|
||||
lpp = stime + lpp + stime_diff
|
||||
|
||||
noise_win, gap_win, signal_win = self.getNoiseWin(phase)
|
||||
snr, snrDB, noiselevel = getSNR(wfdata, (noise_win, gap_win, signal_win), pick - stime_diff)
|
||||
print('SNR of final pick: {}'.format(snr))
|
||||
if snr < 1.5:
|
||||
QMessageBox.warning(self, 'SNR too low', 'WARNING! SNR of final pick below 1.5! SNR = {}'.format(snr))
|
||||
|
||||
# get first motion and quality classes
|
||||
FM = ''
|
||||
if self.getPhaseID(phase) == 'P':
|
||||
# get first motion quality of P onset is sufficeint
|
||||
minFMweight = parameter.get('minfmweight')
|
||||
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'),
|
||||
pick -stime_diff)
|
||||
|
||||
|
||||
# save pick times for actual phase
|
||||
phasepicks = dict(epp=epp, lpp=lpp, mpp=mpp, spe=spe,
|
||||
phasepicks = dict(epp=epp, lpp=lpp, mpp=mpp, spe=spe, fm=FM,
|
||||
picker='manual', channel=channel,
|
||||
network=wfdata[0].stats.network)
|
||||
|
||||
@ -1943,7 +1965,13 @@ class PickDlg(QDialog):
|
||||
self.disconnectPressEvent()
|
||||
self.enable_ar_buttons()
|
||||
self.zoomAction.setEnabled(True)
|
||||
#self.pick_block = self.togglePickBlocker()
|
||||
# self.pick_block = self.togglPickBlocker()
|
||||
# self.resetZoom()
|
||||
noise_win, gap_win, signal_win = self.getNoiseWin(phase)
|
||||
snr, snrDB, noiselevel = getSNR(wfdata, (noise_win, gap_win, signal_win), pick - stime_diff)
|
||||
print('SNR of final pick: {}'.format(snr))
|
||||
if snr < 1.5:
|
||||
QMessageBox.warning(self, 'SNR too low', 'WARNING! SNR of final pick below 1.5! SNR = {}'.format(snr))
|
||||
self.leave_picking_mode()
|
||||
self.setDirty(True)
|
||||
|
||||
@ -2017,16 +2045,27 @@ class PickDlg(QDialog):
|
||||
elif picktype == 'auto':
|
||||
color = pick_color_plt(picktype, phaseID, quality)
|
||||
linestyle_mpp, width_mpp = pick_linestyle_plt(picktype, 'mpp')
|
||||
if not textOnly:
|
||||
ax.plot(mpp, ylims[1], color=color, marker='v')
|
||||
ax.plot(mpp, ylims[0], color=color, marker='^')
|
||||
ax.vlines(mpp, ylims[0], ylims[1], color=color, linestyle=linestyle_mpp, linewidth=width_mpp,
|
||||
picker=5, label='{}-Autopick (quality: {})'.format(phase, quality))
|
||||
# append phase text (if textOnly: draw with current ylims)
|
||||
self.phaseText.append(ax.text(mpp, ylims[1], phase, color=color))
|
||||
else:
|
||||
raise TypeError('Unknown picktype {0}'.format(picktype))
|
||||
|
||||
vl = ax.axvline(mpp, ylims[0], ylims[1], color=color, linestyle=linestyle_mpp, linewidth=width_mpp,
|
||||
label='{}-{}-Pick (quality: {})'.format(phase, picktype, quality), picker=5,
|
||||
zorder=baseorder + 9)
|
||||
phaseLineKey = '{}-{}'.format(phase, picktype)
|
||||
self.phaseLines[phaseLineKey] = vl
|
||||
if spe:
|
||||
ax.fill_between([mpp - spe, mpp + spe], ylims[0], ylims[1],
|
||||
alpha=.25, color=color, label='{}-{}-SPE'.format(phase, picktype), zorder=baseorder + 1)
|
||||
if picks['epp']:
|
||||
linestyle_epp, width_epp = pick_linestyle_plt(picktype, 'epp')
|
||||
ax.axvline(epp, ylims[0], ylims[1], color=color, linestyle=linestyle_epp,
|
||||
linewidth=width_epp, label='{}-{}-EPP'.format(phase, picktype), zorder=baseorder + 2)
|
||||
if picks['lpp']:
|
||||
linestyle_lpp, width_lpp = pick_linestyle_plt(picktype, 'lpp')
|
||||
ax.axvline(lpp, ylims[0], ylims[1], color=color, linestyle=linestyle_lpp,
|
||||
linewidth=width_lpp, label='{}-{}-LPP'.format(phase, picktype), zorder=baseorder + 2)
|
||||
if picktype == 'auto':
|
||||
ax.plot(mpp, ylims[1], color=color, marker='v', zorder=baseorder + 3)
|
||||
ax.plot(mpp, ylims[0], color=color, marker='^', zorder=baseorder + 3)
|
||||
# append phase text (if textOnly: draw with current ylims)
|
||||
self.phaseText.append(ax.text(mpp, ylims[1], phase, color=color, zorder=baseorder + 10))
|
||||
ax.legend(loc=1)
|
||||
|
||||
def connect_pick_delete(self):
|
||||
|
Loading…
Reference in New Issue
Block a user