Merge branch 'feature/port-to-py3' of git.geophysik.ruhr-uni-bochum.de:marcel/pylot into feature/port-to-py3

This commit is contained in:
Kaan Cökerim 2022-03-08 12:45:49 +01:00
commit 7c926327dd
8 changed files with 1785 additions and 7615 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
*.pyc *.pyc
*~ *~
.idea
pylot/RELEASE-VERSION pylot/RELEASE-VERSION

View File

@ -91,6 +91,8 @@ from pylot.core.util.array_map import Array_map
from pylot.core.util.structure import DATASTRUCTURE from pylot.core.util.structure import DATASTRUCTURE
from pylot.core.util.thread import Thread, Worker from pylot.core.util.thread import Thread, Worker
from pylot.core.util.version import get_git_version as _getVersionString from pylot.core.util.version import get_git_version as _getVersionString
from pylot.core.io.getEventListFromXML import geteventlistfromxml
from pylot.core.io.getQualitiesfromxml import getQualitiesfromxml
from pylot.styles import style_settings from pylot.styles import style_settings
@ -346,6 +348,9 @@ class MainWindow(QMainWindow):
compare_icon.addPixmap(QPixmap(':/icons/compare_button.png')) compare_icon.addPixmap(QPixmap(':/icons/compare_button.png'))
qualities_icon = QIcon() qualities_icon = QIcon()
qualities_icon.addPixmap(QPixmap(':/icons/pick_qualities_button.png')) qualities_icon.addPixmap(QPixmap(':/icons/pick_qualities_button.png'))
eventlist_xml_icon = QIcon()
eventlist_xml_icon.addPixmap(QPixmap(':/icons/eventlist_xml_button.png'))
self.newProjectAction = self.createAction(self, "&New project ...", self.newProjectAction = self.createAction(self, "&New project ...",
self.createNewProject, self.createNewProject,
QKeySequence.New, newIcon, QKeySequence.New, newIcon,
@ -486,6 +491,11 @@ class MainWindow(QMainWindow):
# LK will be implemented soon, basic script has already (03/2021) been finished # LK will be implemented soon, basic script has already (03/2021) been finished
self.qualities_action.setVisible(True) self.qualities_action.setVisible(True)
self.eventlist_xml_action = self.createAction(parent=self, text='Create Eventlist from XML',
slot=self.eventlistXml, shortcut='Alt+X',
icon=eventlist_xml_icon, tip='Create an Eventlist from a XML File')
self.eventlist_xml_action.setEnabled(False)
printAction = self.createAction(self, "&Print event ...", printAction = self.createAction(self, "&Print event ...",
self.show_event_information, QKeySequence.Print, self.show_event_information, QKeySequence.Print,
print_icon, print_icon,
@ -549,7 +559,7 @@ class MainWindow(QMainWindow):
' the complete project on grid engine.') ' the complete project on grid engine.')
self.auto_pick_sge.setEnabled(False) self.auto_pick_sge.setEnabled(False)
pickActions = (self.auto_tune, self.auto_pick, self.compare_action, self.qualities_action) pickActions = (self.auto_tune, self.auto_pick, self.compare_action, self.qualities_action, self.eventlist_xml_action)
# pickToolBar = self.addToolBar("PickTools") # pickToolBar = self.addToolBar("PickTools")
# pickToolActions = (selectStation, ) # pickToolActions = (selectStation, )
@ -1646,6 +1656,14 @@ class MainWindow(QMainWindow):
self.cmpw.show() self.cmpw.show()
def pickQualities(self): def pickQualities(self):
path = self._inputs['rootpath'] + '/' + self._inputs['datapath'] + '/' + self._inputs['database']
getQualitiesfromxml(path)
return
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 return
def compareMulti(self): def compareMulti(self):
@ -2089,6 +2107,7 @@ class MainWindow(QMainWindow):
if event.pylot_picks or event.pylot_autopicks: if event.pylot_picks or event.pylot_autopicks:
self.locateEventAction.setEnabled(True) self.locateEventAction.setEnabled(True)
self.qualities_action.setEnabled(True) self.qualities_action.setEnabled(True)
self.eventlist_xml_action.setEnabled(True)
if True in self.comparable.values(): if True in self.comparable.values():
self.compare_action.setEnabled(True) self.compare_action.setEnabled(True)
self.draw() self.draw()
@ -2161,6 +2180,7 @@ class MainWindow(QMainWindow):
self.loadpilotevent.setEnabled(False) self.loadpilotevent.setEnabled(False)
self.compare_action.setEnabled(False) self.compare_action.setEnabled(False)
self.qualities_action.setEnabled(False) self.qualities_action.setEnabled(False)
self.eventlist_xml_action.setEnabled(False)
self.locateEventAction.setEnabled(False) self.locateEventAction.setEnabled(False)
if not refresh_plot: if not refresh_plot:
self.wf_scroll_area.setVisible(False) self.wf_scroll_area.setVisible(False)
@ -2541,7 +2561,13 @@ class MainWindow(QMainWindow):
self.drawPicks(station) self.drawPicks(station)
self.draw() self.draw()
if self.nextStation: if self.nextStation:
if not self.get_loc_flag() and self.check4Loc():
self.locateEventAction.setEnabled(True)
self.set_loc_flag(True)
elif self.get_loc_flag() and not self.check4Loc():
self.set_loc_flag(False)
self.pickDialog(wfID - 1) self.pickDialog(wfID - 1)
else: else:
self.update_status('picks discarded ({0})'.format(station)) self.update_status('picks discarded ({0})'.format(station))
if not self.get_loc_flag() and self.check4Loc(): if not self.get_loc_flag() and self.check4Loc():

View File

@ -30,6 +30,7 @@
<file>icons/openloc.png</file> <file>icons/openloc.png</file>
<file>icons/compare_button.png</file> <file>icons/compare_button.png</file>
<file>icons/pick_qualities_button.png</file> <file>icons/pick_qualities_button.png</file>
<file>icons/eventlist_xml_button.png</file>
<file>icons/locate_button.png</file> <file>icons/locate_button.png</file>
<file>icons/Matlab_PILOT_icon.png</file> <file>icons/Matlab_PILOT_icon.png</file>
<file>icons/printer.png</file> <file>icons/printer.png</file>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,79 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Script to get event parameters from PyLoT-xml file to write
them into eventlist.
LK, igem, 03/2021
Edited for use in PyLoT
JG, igem, 01/2022
"""
import pdb
import os
import argparse
import numpy as np
import matplotlib.pyplot as plt
from obspy.core.event import read_events
from pyproj import Proj
import glob
"""
Creates an eventlist file summarizing all events found in a certain folder. Only called by pressing UI Button eventlis_xml_action
:rtype:
:param path: Path to root folder where single Event folder are to found
"""
def geteventlistfromxml(path, outpath):
p = Proj(proj='utm', zone=32, ellps='WGS84')
# open eventlist file and write header
evlist = outpath + '/eventlist'
evlistobj = open(evlist, 'w')
evlistobj.write('EventID Date To Lat Lon EAST NORTH Dep Ml NoP NoS RMS errH errZ Gap \n')
# data path
dp = path + "/e*/*.xml"
# list of all available xml-files
xmlnames = glob.glob(dp)
# read all onset weights
for names in xmlnames:
print("Getting location parameters from {}".format(names))
cat = read_events(names)
try:
st = cat.events[0].origins[0].time
Lat = cat.events[0].origins[0].latitude
Lon = cat.events[0].origins[0].longitude
EAST, NORTH = p(Lon, Lat)
Dep = cat.events[0].origins[0].depth / 1000
Ml = cat.events[0].magnitudes[1].mag
NoP = []
NoS = []
except IndexError:
print ('Insufficient data found for event (not localised): ' + names.split('/')[-1].split('_')[-1][:-4] + ' Skipping event for eventlist.' )
continue
for i in range(len(cat.events[0].origins[0].arrivals)):
if cat.events[0].origins[0].arrivals[i].phase == 'P':
NoP.append(cat.events[0].origins[0].arrivals[i].phase)
elif cat.events[0].origins[0].arrivals[i].phase == 'S':
NoS.append(cat.events[0].origins[0].arrivals[i].phase)
#NoP = cat.events[0].origins[0].quality.used_station_count
errH = cat.events[0].origins[0].origin_uncertainty.max_horizontal_uncertainty
errZ = cat.events[0].origins[0].depth_errors.uncertainty
Gap = cat.events[0].origins[0].quality.azimuthal_gap
#evID = names.split('/')[6]
evID = names.split('/')[-1].split('_')[-1][:-4]
Date = str(st.year) + str('%02d' % st.month) + str('%02d' % st.day)
To = str('%02d' % st.hour) + str('%02d' % st.minute) + str('%02d' % st.second) + \
'.' + str('%06d' % st.microsecond)
# write into eventlist
evlistobj.write('%s %s %s %9.6f %9.6f %13.6f %13.6f %8.6f %3.1f %d %d NaN %d %d %d\n' %(evID, \
Date, To, Lat, Lon, EAST, NORTH, Dep, Ml, len(NoP), len(NoS), errH, errZ, Gap))
print ('Adding Event ' + names.split('/')[-1].split('_')[-1][:-4] + ' to eventlist')
print('Eventlist created and saved in: ' + outpath)
evlistobj.close()

View File

@ -0,0 +1,139 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Script to get onset uncertainties from Quakeml.xml files created by PyLoT.
Uncertainties are tranformed into quality classes and visualized via histogram if desired.
Ludger Küperkoch, BESTEC GmbH, 07/2017
rev.: Ludger Küperkoch, igem, 10/2020
Edited for usage in PyLoT: Jeldrik Gaal, igem, 01/2022
"""
import argparse
import numpy as np
import matplotlib.pyplot as plt
from obspy.core.event import read_events
import glob
def getQualitiesfromxml(path):
# uncertainties
ErrorsP = [0.02, 0.04, 0.08, 0.16]
ErrorsS = [0.04, 0.08, 0.16, 0.32]
Pw0 = []
Pw1 = []
Pw2 = []
Pw3 = []
Pw4 = []
Sw0 = []
Sw1 = []
Sw2 = []
Sw3 = []
Sw4 = []
# data path
dp = path + '/e*/*.xml'
# list of all available xml-files
xmlnames = glob.glob(dp)
# read all onset weights
for names in xmlnames:
print("Getting onset weights from {}".format(names))
cat = read_events(names)
arrivals = cat.events[0].picks
for Pick in arrivals:
if Pick.phase_hint[0] == 'P':
if Pick.time_errors.uncertainty <= ErrorsP[0]:
Pw0.append(Pick.time_errors.uncertainty)
elif Pick.time_errors.uncertainty > ErrorsP[0] and \
Pick.time_errors.uncertainty <= ErrorsP[1]:
Pw1.append(Pick.time_errors.uncertainty)
elif Pick.time_errors.uncertainty > ErrorsP[1] and \
Pick.time_errors.uncertainty <= ErrorsP[2]:
Pw2.append(Pick.time_errors.uncertainty)
elif Pick.time_errors.uncertainty > ErrorsP[2] and \
Pick.time_errors.uncertainty <= ErrorsP[3]:
Pw3.append(Pick.time_errors.uncertainty)
elif Pick.time_errors.uncertainty > ErrorsP[3]:
Pw4.append(Pick.time_errors.uncertainty)
else:
pass
elif Pick.phase_hint[0] == 'S':
if Pick.time_errors.uncertainty <= ErrorsS[0]:
Sw0.append(Pick.time_errors.uncertainty)
elif Pick.time_errors.uncertainty > ErrorsS[0] and \
Pick.time_errors.uncertainty <= ErrorsS[1]:
Sw1.append(Pick.time_errors.uncertainty)
elif Pick.time_errors.uncertainty > ErrorsS[1] and \
Pick.time_errors.uncertainty <= ErrorsS[2]:
Sw2.append(Pick.time_errors.uncertainty)
elif Pick.time_errors.uncertainty > ErrorsS[2] and \
Pick.time_errors.uncertainty <= ErrorsS[3]:
Sw3.append(Pick.time_errors.uncertainty)
elif Pick.time_errors.uncertainty > ErrorsS[3]:
Sw4.append(Pick.time_errors.uncertainty)
else:
pass
else:
print("Phase hint not defined for picking!")
pass
# get percentage of weights
numPweights = np.sum([len(Pw0), len(Pw1), len(Pw2), len(Pw3), len(Pw4)])
numSweights = np.sum([len(Sw0), len(Sw1), len(Sw2), len(Sw3), len(Sw4)])
try:
P0perc = 100.0 / numPweights * len(Pw0)
except:
P0perc = 0
try:
P1perc = 100.0 / numPweights * len(Pw1)
except:
P1perc = 0
try:
P2perc = 100.0 / numPweights * len(Pw2)
except:
P2perc = 0
try:
P3perc = 100.0 / numPweights * len(Pw3)
except:
P3perc = 0
try:
P4perc = 100.0 / numPweights * len(Pw4)
except:
P4perc = 0
try:
S0perc = 100.0 / numSweights * len(Sw0)
except:
Soperc = 0
try:
S1perc = 100.0 / numSweights * len(Sw1)
except:
S1perc = 0
try:
S2perc = 100.0 / numSweights * len(Sw2)
except:
S2perc = 0
try:
S3perc = 100.0 / numSweights * len(Sw3)
except:
S3perc = 0
try:
S4perc = 100.0 / numSweights * len(Sw4)
except:
S4perc = 0
weights = ('0', '1', '2', '3', '4')
y_pos = np.arange(len(weights))
width = 0.34
p1, = plt.bar(0 - width, P0perc, width, color='black')
p2, = plt.bar(0, S0perc, width, color='red')
plt.bar(y_pos - width, [P0perc, P1perc, P2perc, P3perc, P4perc], width, color='black')
plt.bar(y_pos, [S0perc, S1perc, S2perc, S3perc, S4perc], width, color='red')
plt.ylabel('%')
plt.xticks(y_pos, weights)
plt.xlim([-0.5, 4.5])
plt.xlabel('Qualities')
plt.title('{0} P-Qualities, {1} S-Qualities'.format(numPweights, numSweights))
plt.legend([p1, p2], ['P-Weights', 'S-Weights'])
plt.show()

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import pdb
import glob import glob
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
@ -512,13 +512,13 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
and FOCMEC- and HASH-input files and FOCMEC- and HASH-input files
:type eventinfo: `obspy.core.event.Event` object :type eventinfo: `obspy.core.event.Event` object
""" """
if fformat == 'NLLoc': if fformat == 'NLLoc':
print("Writing phases to %s for NLLoc" % filename) print("Writing phases to %s for NLLoc" % filename)
fid = open("%s" % filename, 'w') fid = open("%s" % filename, 'w')
# write header # write header
fid.write('# EQEVENT: %s Label: EQ%s Loc: X 0.00 Y 0.00 Z 10.00 OT 0.00 \n' % fid.write('# EQEVENT: %s Label: EQ%s Loc: X 0.00 Y 0.00 Z 10.00 OT 0.00 \n' %
(parameter.get('database'), parameter.get('eventID'))) (parameter.get('database'), parameter.get('eventID')))
arrivals = chooseArrivals(arrivals)
for key in arrivals: for key in arrivals:
# P onsets # P onsets
if arrivals[key].has_key('P'): if arrivals[key].has_key('P'):
@ -573,6 +573,8 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
except KeyError as e: except KeyError as e:
print(str(e) + '; no weight set during processing') print(str(e) + '; no weight set during processing')
Ao = arrivals[key]['S']['Ao'] # peak-to-peak amplitude Ao = arrivals[key]['S']['Ao'] # peak-to-peak amplitude
if Ao == None:
Ao = 0.0
#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 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, fid.write('%s ? ? ? S %s %d%02d%02d %02d%02d %7.4f GAU 0 %9.2f 0 0 %d \n' % (key,
fm, fm,
@ -592,6 +594,7 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
# write header # write header
fid.write(' %s\n' % fid.write(' %s\n' %
parameter.get('eventID')) parameter.get('eventID'))
arrivals = chooseArrivals(arrivals)
for key in arrivals: for key in arrivals:
if arrivals[key]['P']['weight'] < 4: if arrivals[key]['P']['weight'] < 4:
stat = key stat = key
@ -668,6 +671,7 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
fid = open("%s" % filename, 'w') fid = open("%s" % filename, 'w')
# write header # write header
fid.write('%s, event %s \n' % (parameter.get('database'), parameter.get('eventID'))) fid.write('%s, event %s \n' % (parameter.get('database'), parameter.get('eventID')))
arrivals = chooseArrivals(arrivals)
for key in arrivals: for key in arrivals:
# P onsets # P onsets
if arrivals[key].has_key('P') and arrivals[key]['P']['mpp'] is not None: if arrivals[key].has_key('P') and arrivals[key]['P']['mpp'] is not None:
@ -763,30 +767,33 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
evt = ope.Event(resource_id=eventinfo['resource_id']) evt = ope.Event(resource_id=eventinfo['resource_id'])
evt.picks = arrivals evt.picks = arrivals
arrivals = picksdict_from_picks(evt) arrivals = picksdict_from_picks(evt)
for key in arrivals: # check for automatic and manual picks
# prefer manual picks
usedarrivals = chooseArrival(arrivals)
for key in usedarrivals:
# P onsets # P onsets
if arrivals[key].has_key('P'): if usedarrivals[key].has_key('P'):
if arrivals[key]['P']['weight'] < 4: if usedarrivals[key]['P']['weight'] < 4:
n += 1 n += 1
stat = key stat = key
if len(stat) > 4: # VELEST handles only 4-string station IDs if len(stat) > 4: # VELEST handles only 4-string station IDs
stat = stat[1:5] stat = stat[1:5]
Ponset = arrivals[key]['P']['mpp'] Ponset = usedarrivals[key]['P']['mpp']
Pweight = arrivals[key]['P']['weight'] Pweight = usedarrivals[key]['P']['weight']
Prt = Ponset - stime # onset time relative to source time Prt = Ponset - stime # onset time relative to source time
if n % 6 != 0: if n % 6 != 0:
fid.write('%-4sP%d%6.2f' % (stat, Pweight, Prt)) fid.write('%-4sP%d%6.2f' % (stat, Pweight, Prt))
else: else:
fid.write('%-4sP%d%6.2f\n' % (stat, Pweight, Prt)) fid.write('%-4sP%d%6.2f\n' % (stat, Pweight, Prt))
# S onsets # S onsets
if arrivals[key].has_key('S'): if usedarrivals[key].has_key('S'):
if arrivals[key]['S']['weight'] < 4: if usedarrivals[key]['S']['weight'] < 4:
n += 1 n += 1
stat = key stat = key
if len(stat) > 4: # VELEST handles only 4-string station IDs if len(stat) > 4: # VELEST handles only 4-string station IDs
stat = stat[1:5] stat = stat[1:5]
Sonset = arrivals[key]['S']['mpp'] Sonset = usedarrivals[key]['S']['mpp']
Sweight = arrivals[key]['S']['weight'] Sweight = usedarrivals[key]['S']['weight']
Srt = Ponset - stime # onset time relative to source time Srt = Ponset - stime # onset time relative to source time
if n % 6 != 0: if n % 6 != 0:
fid.write('%-4sS%d%6.2f' % (stat, Sweight, Srt)) fid.write('%-4sS%d%6.2f' % (stat, Sweight, Srt))
@ -804,8 +811,12 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
print("No source origin calculated yet, thus no hypoDD-infile creation possible!") print("No source origin calculated yet, thus no hypoDD-infile creation possible!")
return return
stime = eventsource['time'] stime = eventsource['time']
event = parameter.get('eventID') try:
event = eventinfo['pylot_id']
hddID = event.split('.')[0][1:5] hddID = event.split('.')[0][1:5]
except:
print ("Error 1111111!")
hddID = "00000"
# write header # write header
fid.write('# %d %d %d %d %d %5.2f %7.4f +%6.4f %7.4f %4.2f 0.1 0.5 %4.2f %s\n' % ( fid.write('# %d %d %d %d %d %5.2f %7.4f +%6.4f %7.4f %4.2f 0.1 0.5 %4.2f %s\n' % (
stime.year, stime.month, stime.day, stime.hour, stime.minute, stime.second, stime.year, stime.month, stime.day, stime.hour, stime.minute, stime.second,
@ -817,17 +828,20 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
evt = ope.Event(resource_id=eventinfo['resource_id']) evt = ope.Event(resource_id=eventinfo['resource_id'])
evt.picks = arrivals evt.picks = arrivals
arrivals = picksdict_from_picks(evt) arrivals = picksdict_from_picks(evt)
for key in arrivals: # check for automatic and manual picks
if arrivals[key].has_key('P'): # prefer manual picks
usedarrivals = chooseArrival(arrivals)
for key in usedarrivals:
if usedarrivals[key].has_key('P'):
# P onsets # P onsets
if arrivals[key]['P']['weight'] < 4: if usedarrivals[key]['P']['weight'] < 4:
Ponset = arrivals[key]['P']['mpp'] Ponset = usedarrivals[key]['P']['mpp']
Prt = Ponset - stime # onset time relative to source time Prt = Ponset - stime # onset time relative to source time
fid.write('%s %6.3f 1 P\n' % (key, Prt)) fid.write('%s %6.3f 1 P\n' % (key, Prt))
if arrivals[key].has_key('S'): if usedarrivals[key].has_key('S'):
# S onsets # S onsets
if arrivals[key]['S']['weight'] < 4: if usedarrivals[key]['S']['weight'] < 4:
Sonset = arrivals[key]['S']['mpp'] Sonset = usedarrivals[key]['S']['mpp']
Srt = Sonset - stime # onset time relative to source time Srt = Sonset - stime # onset time relative to source time
fid.write('%-5s %6.3f 1 S\n' % (key, Srt)) fid.write('%-5s %6.3f 1 S\n' % (key, Srt))
@ -865,9 +879,12 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
evt = ope.Event(resource_id=eventinfo['resource_id']) evt = ope.Event(resource_id=eventinfo['resource_id'])
evt.picks = arrivals evt.picks = arrivals
arrivals = picksdict_from_picks(evt) arrivals = picksdict_from_picks(evt)
for key in arrivals: # check for automatic and manual picks
if arrivals[key].has_key('P'): # prefer manual picks
if arrivals[key]['P']['weight'] < 4 and arrivals[key]['P']['fm'] is not None: usedarrivals = chooseArrival(arrivals)
for key in usedarrivals:
if usedarrivals[key].has_key('P'):
if usedarrivals[key]['P']['weight'] < 4 and usedarrivals[key]['P']['fm'] is not None:
stat = key stat = key
for i in range(len(picks)): for i in range(len(picks)):
station = picks[i].waveform_id.station_code station = picks[i].waveform_id.station_code
@ -886,7 +903,7 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
fid.write('%-4s %6.2f %6.2f%s \n' % (stat, fid.write('%-4s %6.2f %6.2f%s \n' % (stat,
az, az,
inz, inz,
arrivals[key]['P']['fm'])) usedarrivals[key]['P']['fm']))
break break
fid.close() fid.close()
@ -944,7 +961,8 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
eventsource['quality']['used_phase_count'], eventsource['quality']['used_phase_count'],
erh, erz, eventinfo.magnitudes[0]['mag'], erh, erz, eventinfo.magnitudes[0]['mag'],
hashID)) hashID))
# Prefer Manual Picks over automatic ones if possible
arrivals = chooseArrivals(arrivals)
# write phase lines # write phase lines
for key in arrivals: for key in arrivals:
if arrivals[key].has_key('P'): if arrivals[key].has_key('P'):
@ -991,6 +1009,25 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
fid1.close() fid1.close()
fid2.close() fid2.close()
def chooseArrival(arrivals):
"""
takes arrivals and returns the manual picks if manual and automatic ones are there
returns automatic picks if only automatic picks are there
:param arrivals: 'dictionary' with automatic and or manual 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']:
usedarrivals = arrivals['manual']
elif arrivals['auto']:
usedarrivals = arrivals['auto']
elif arrivals['manual']:
usedarrivals = arrivals['manual']
return usedarrivals
def merge_picks(event, picks): def merge_picks(event, picks):
""" """

View File

@ -34,7 +34,7 @@ from PySide2.QtGui import QIcon, QPixmap, QKeySequence
from PySide2.QtWidgets import QAction, QApplication, QCheckBox, QComboBox, \ from PySide2.QtWidgets import QAction, QApplication, QCheckBox, QComboBox, \
QDateTimeEdit, QDialog, QDialogButtonBox, QDoubleSpinBox, QGroupBox, \ QDateTimeEdit, QDialog, QDialogButtonBox, QDoubleSpinBox, QGroupBox, \
QGridLayout, QLabel, QLineEdit, QMessageBox, \ QGridLayout, QLabel, QLineEdit, QMessageBox, \
QSpinBox, QTabWidget, QToolBar, QVBoxLayout, QHBoxLayout, QWidget, \ QTabWidget, QToolBar, QVBoxLayout, QHBoxLayout, QWidget, \
QPushButton, QFileDialog, QInputDialog QPushButton, QFileDialog, QInputDialog
from PySide2.QtCore import QSettings, Qt, QUrl, Signal, Slot from PySide2.QtCore import QSettings, Qt, QUrl, Signal, Slot
from PySide2.QtWebEngineWidgets import QWebEngineView as QWebView from PySide2.QtWebEngineWidgets import QWebEngineView as QWebView
@ -70,6 +70,18 @@ else:
# icons_rc = icons_rc # icons_rc = icons_rc
class QSpinBox(QtWidgets.QSpinBox):
''' Custom SpinBox, insensitive to Mousewheel (prevents accidental changes when scrolling through parameters) '''
def wheelEvent(self, event):
event.ignore()
class QDoubleSpinBox(QtWidgets.QDoubleSpinBox):
''' Custom DoubleSpinBox, insensitive to Mousewheel (prevents accidental changes when scrolling through parameters) '''
def wheelEvent(self, event):
event.ignore()
def getDataType(parent): def getDataType(parent):
type = QInputDialog().getItem(parent, "Select phases type", "Type:", type = QInputDialog().getItem(parent, "Select phases type", "Type:",
["manual", "automatic"]) ["manual", "automatic"])
@ -4027,11 +4039,11 @@ class PylotParaBox(QtWidgets.QWidget):
if typ == str: if typ == str:
box = QtWidgets.QLineEdit() box = QtWidgets.QLineEdit()
elif typ == float: elif typ == float:
box = QtWidgets.QDoubleSpinBox() box = QDoubleSpinBox()
box.setDecimals(4) box.setDecimals(4)
box.setRange(-10e4, 10e4) box.setRange(-10e4, 10e4)
elif typ == int: elif typ == int:
box = QtWidgets.QSpinBox() box = QSpinBox()
elif typ == bool: elif typ == bool:
box = QtWidgets.QCheckBox() box = QtWidgets.QCheckBox()
else: else:
@ -4224,7 +4236,7 @@ class PylotParaBox(QtWidgets.QWidget):
def setValue(self, box, value): def setValue(self, box, value):
if type(box) == QtWidgets.QLineEdit: if type(box) == QtWidgets.QLineEdit:
box.setText(str(value)) box.setText(str(value))
elif type(box) == QtWidgets.QSpinBox or type(box) == QtWidgets.QDoubleSpinBox: elif type(box) == QSpinBox or type(box) == QDoubleSpinBox:
if not value: if not value:
value = 0. value = 0.
box.setValue(value) box.setValue(value)
@ -4241,7 +4253,7 @@ class PylotParaBox(QtWidgets.QWidget):
def getValue(self, box): def getValue(self, box):
if type(box) == QtWidgets.QLineEdit: if type(box) == QtWidgets.QLineEdit:
value = str(box.text()) value = str(box.text())
elif type(box) == QtWidgets.QSpinBox or type(box) == QtWidgets.QDoubleSpinBox: elif type(box) == QSpinBox or type(box) == QDoubleSpinBox:
value = box.value() value = box.value()
elif type(box) == QtWidgets.QCheckBox: elif type(box) == QtWidgets.QCheckBox:
value = box.isChecked() value = box.isChecked()
@ -4839,7 +4851,7 @@ class GraphicsTab(PropTab):
if not nth_sample: if not nth_sample:
nth_sample = 1 nth_sample = 1
self.spinbox_nth_sample = QtWidgets.QSpinBox() self.spinbox_nth_sample = QSpinBox()
label = QLabel('nth sample') label = QLabel('nth sample')
label.setToolTip('Plot every nth sample (to speed up plotting)') label.setToolTip('Plot every nth sample (to speed up plotting)')
self.spinbox_nth_sample.setMinimum(1) self.spinbox_nth_sample.setMinimum(1)