WIP: Simplify data structure #39
499
PyLoT.py
499
PyLoT.py
@ -108,6 +108,7 @@ locateTool = dict(nll=nll)
|
|||||||
|
|
||||||
|
|
||||||
class MainWindow(QMainWindow):
|
class MainWindow(QMainWindow):
|
||||||
|
_metadata: Metadata
|
||||||
__version__ = _getVersionString()
|
__version__ = _getVersionString()
|
||||||
closing = Signal()
|
closing = Signal()
|
||||||
|
|
||||||
@ -241,20 +242,6 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
self.loc = False
|
self.loc = False
|
||||||
|
|
||||||
def init_config_files(self, infile):
|
|
||||||
pylot_config_dir = os.path.join(os.path.expanduser('~'), '.pylot')
|
|
||||||
if not os.path.exists(pylot_config_dir):
|
|
||||||
os.mkdir(pylot_config_dir)
|
|
||||||
|
|
||||||
self._inputs = PylotParameter(infile)
|
|
||||||
if not infile:
|
|
||||||
self._inputs.reset_defaults()
|
|
||||||
# check for default pylot.in-file
|
|
||||||
infile = os.path.join(pylot_config_dir, '.pylot.in')
|
|
||||||
logging.warning('Using default input file {}'.format(infile))
|
|
||||||
self._inputs.export2File(infile)
|
|
||||||
self.infile = infile
|
|
||||||
|
|
||||||
def setupUi(self, use_logwidget=False):
|
def setupUi(self, use_logwidget=False):
|
||||||
try:
|
try:
|
||||||
self.startTime = min(
|
self.startTime = min(
|
||||||
@ -911,7 +898,7 @@ class MainWindow(QMainWindow):
|
|||||||
return self._metadata
|
return self._metadata
|
||||||
|
|
||||||
@metadata.setter
|
@metadata.setter
|
||||||
def metadata(self, value):
|
def metadata(self, value: Metadata):
|
||||||
self._metadata = value
|
self._metadata = value
|
||||||
|
|
||||||
def updateFilteroptions(self):
|
def updateFilteroptions(self):
|
||||||
@ -1069,9 +1056,6 @@ class MainWindow(QMainWindow):
|
|||||||
self.refreshEvents()
|
self.refreshEvents()
|
||||||
self.setDirty(True)
|
self.setDirty(True)
|
||||||
|
|
||||||
def add_recentfile(self, event):
|
|
||||||
self.recentfiles.insert(0, event)
|
|
||||||
|
|
||||||
def set_button_border_color(self, button, color=None):
|
def set_button_border_color(self, button, color=None):
|
||||||
'''
|
'''
|
||||||
Set background color of a button.
|
Set background color of a button.
|
||||||
@ -1180,26 +1164,53 @@ class MainWindow(QMainWindow):
|
|||||||
def getLastEvent(self):
|
def getLastEvent(self):
|
||||||
return self.recentfiles[0]
|
return self.recentfiles[0]
|
||||||
|
|
||||||
def add_events(self):
|
def add_events(self) -> None:
|
||||||
'''
|
'''
|
||||||
Creates and adds events by user selection of event folders to GUI.
|
Creates and adds events by user selection of event folders to GUI.
|
||||||
'''
|
'''
|
||||||
if not self.project:
|
if not self.project:
|
||||||
self.createNewProject()
|
self.createNewProject()
|
||||||
|
|
||||||
|
eventlist, basepath = self.get_event_directories()
|
||||||
|
if not eventlist:
|
||||||
|
return
|
||||||
|
|
||||||
|
eventlist = self.set_data_structure(basepath, eventlist)
|
||||||
|
if not eventlist:
|
||||||
|
self.show_no_events_message()
|
||||||
|
return
|
||||||
|
|
||||||
|
dirs = self.initialize_directory_structure(eventlist[0])
|
||||||
|
if not dirs:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.update_project_settings(dirs)
|
||||||
|
|
||||||
|
self.project.add_eventlist(eventlist)
|
||||||
|
self.init_events()
|
||||||
|
self.setDirty(True)
|
||||||
|
|
||||||
|
def get_event_directories(self):
|
||||||
ed = GetExistingDirectories(self, 'Select event directories...')
|
ed = GetExistingDirectories(self, 'Select event directories...')
|
||||||
if ed.exec_():
|
if not ed.exec_():
|
||||||
|
return None, None
|
||||||
|
|
||||||
eventlist = [event for event in ed.selectedFiles() if not event.endswith('EVENTS-INFO')]
|
eventlist = [event for event in ed.selectedFiles() if not event.endswith('EVENTS-INFO')]
|
||||||
basepath = eventlist[0].split(os.path.basename(eventlist[0]))[0]
|
basepath = eventlist[0].split(os.path.basename(eventlist[0]))[0]
|
||||||
# small hack: if a file "eventlist.txt" is found in the basepath use only those events specified inside
|
eventlist = self.filter_eventlist_with_file(eventlist, basepath)
|
||||||
|
return eventlist, basepath
|
||||||
|
|
||||||
|
def filter_eventlist_with_file(self, eventlist, basepath):
|
||||||
eventlist_file = os.path.join(basepath, 'eventlist.txt')
|
eventlist_file = os.path.join(basepath, 'eventlist.txt')
|
||||||
if os.path.isfile(eventlist_file):
|
if os.path.isfile(eventlist_file):
|
||||||
with open(eventlist_file, 'r') as infile:
|
with open(eventlist_file, 'r') as infile:
|
||||||
eventlist_subset = [os.path.join(basepath, filename.split('\n')[0]) for filename in
|
eventlist_subset = [os.path.join(basepath, filename.strip()) for filename in infile]
|
||||||
infile.readlines()]
|
print(
|
||||||
msg = 'Found file "eventlist.txt" in database path. WILL ONLY USE SELECTED EVENTS out of {} events ' \
|
f'Found file "eventlist.txt" in database path. WILL ONLY USE SELECTED EVENTS out of {len(eventlist_subset)} events contained in this subset')
|
||||||
'contained in this subset'
|
|
||||||
print(msg.format(len(eventlist_subset)))
|
|
||||||
eventlist = [eventname for eventname in eventlist if eventname in eventlist_subset]
|
eventlist = [eventname for eventname in eventlist if eventname in eventlist_subset]
|
||||||
|
return eventlist
|
||||||
|
|
||||||
|
def set_data_structure(self, basepath, eventlist):
|
||||||
if check_obspydmt_structure(basepath):
|
if check_obspydmt_structure(basepath):
|
||||||
print('Recognized obspyDMT structure in selected files. Setting Datastructure to ObspyDMT')
|
print('Recognized obspyDMT structure in selected files. Setting Datastructure to ObspyDMT')
|
||||||
self.dataStructure = DATASTRUCTURE['obspyDMT']()
|
self.dataStructure = DATASTRUCTURE['obspyDMT']()
|
||||||
@ -1208,76 +1219,62 @@ class MainWindow(QMainWindow):
|
|||||||
print('Setting Datastructure to PILOT')
|
print('Setting Datastructure to PILOT')
|
||||||
self.dataStructure = DATASTRUCTURE['PILOT']()
|
self.dataStructure = DATASTRUCTURE['PILOT']()
|
||||||
eventlist = check_all_pylot(eventlist)
|
eventlist = check_all_pylot(eventlist)
|
||||||
if not eventlist:
|
return eventlist
|
||||||
|
|
||||||
|
def show_no_events_message(self):
|
||||||
print('No events found! Expected structure for event folders: [eEVID.DOY.YR],\n'
|
print('No events found! Expected structure for event folders: [eEVID.DOY.YR],\n'
|
||||||
' e.g. eventID=1, doy=2, yr=2016: e0001.002.16 or obspyDMT database')
|
' e.g. eventID=1, doy=2, yr=2016: e0001.002.16 or obspyDMT database')
|
||||||
return
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
if not self.project:
|
|
||||||
print('No project found.')
|
|
||||||
return
|
|
||||||
|
|
||||||
# get path from first event in list and split them
|
def initialize_directory_structure(self, path):
|
||||||
path = eventlist[0]
|
|
||||||
try:
|
try:
|
||||||
system_name = platform.system()
|
system_name = platform.system()
|
||||||
if system_name in ["Linux", "Darwin"]:
|
if system_name in ["Linux", "Darwin"]:
|
||||||
dirs = {
|
dirs = {
|
||||||
'database': path.split('/')[-2],
|
'database': path.split('/')[-2],
|
||||||
'datapath': os.path.split(path)[0], # path.split('/')[-3],
|
'datapath': os.path.split(path)[0],
|
||||||
'rootpath': '/' + os.path.join(*path.split('/')[:-3])
|
'rootpath': '/' + os.path.join(*path.split('/')[:-3])
|
||||||
}
|
}
|
||||||
elif system_name == "Windows":
|
elif system_name == "Windows":
|
||||||
rootpath = path.split('/')[:-3]
|
rootpath = path.split('/')[:-3]
|
||||||
rootpath[0] += '/'
|
rootpath[0] += '/'
|
||||||
dirs = {
|
dirs = {
|
||||||
# TODO: Arrange path to meet Win standards
|
|
||||||
'database': path.split('/')[-2],
|
'database': path.split('/')[-2],
|
||||||
'datapath': path.split('/')[-3],
|
'datapath': path.split('/')[-3],
|
||||||
'rootpath': os.path.join(*rootpath)
|
'rootpath': os.path.join(*rootpath)
|
||||||
}
|
}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
dirs = {
|
print(f'Warning: Could not automatically init folder structure. ({e})')
|
||||||
'database': '',
|
return None
|
||||||
'datapath': '',
|
|
||||||
'rootpath': ''
|
|
||||||
}
|
|
||||||
print('Warning: Could not automatically init folder structure. ({})'.format(e))
|
|
||||||
|
|
||||||
|
self.save_directory_settings(dirs['datapath'])
|
||||||
|
return dirs
|
||||||
|
|
||||||
|
def save_directory_settings(self, datapath):
|
||||||
settings = QSettings()
|
settings = QSettings()
|
||||||
settings.setValue("data/dataRoot", dirs['datapath']) # d irs['rootpath'])
|
settings.setValue("data/dataRoot", datapath)
|
||||||
settings.sync()
|
settings.sync()
|
||||||
|
|
||||||
|
def update_project_settings(self, dirs):
|
||||||
if not self.project.eventlist:
|
if not self.project.eventlist:
|
||||||
# init parameter object
|
self.set_parameter(show=False)
|
||||||
self.setParameter(show=False)
|
|
||||||
# hide all parameter (show all needed parameter later)
|
|
||||||
self.paraBox.hide_parameter()
|
self.paraBox.hide_parameter()
|
||||||
for directory in dirs.keys():
|
self.update_paraBox(dirs)
|
||||||
# set parameter
|
if not self.paraBox.get_groupbox_dialog('Directories').exec_():
|
||||||
box = self.paraBox.boxes[directory]
|
|
||||||
self.paraBox.setValue(box, dirs[directory])
|
|
||||||
# show needed parameter in box
|
|
||||||
self.paraBox.show_parameter(directory)
|
|
||||||
dirs_box = self.paraBox.get_groupbox_dialog('Directories')
|
|
||||||
if not dirs_box.exec_():
|
|
||||||
return
|
return
|
||||||
self.project.rootpath = dirs['rootpath']
|
self.project.rootpath = dirs['rootpath']
|
||||||
self.project.datapath = dirs['datapath']
|
self.project.datapath = dirs['datapath']
|
||||||
else:
|
else:
|
||||||
if hasattr(self.project, 'datapath'):
|
if hasattr(self.project, 'datapath') and self.project.datapath != dirs['datapath']:
|
||||||
if not self.project.datapath == dirs['datapath']:
|
QMessageBox.warning(self, "PyLoT Warning", 'Datapath mismatch to current project!')
|
||||||
QMessageBox.warning(self, "PyLoT Warning",
|
|
||||||
'Datapath missmatch to current project!')
|
|
||||||
return
|
return
|
||||||
else:
|
|
||||||
self.project.rootpath = dirs['rootpath']
|
self.project.rootpath = dirs['rootpath']
|
||||||
self.project.datapath = dirs['datapath']
|
self.project.datapath = dirs['datapath']
|
||||||
|
|
||||||
self.project.add_eventlist(eventlist)
|
def update_paraBox(self, dirs):
|
||||||
self.init_events()
|
for directory, path in dirs.items():
|
||||||
self.setDirty(True)
|
box = self.paraBox.boxes[directory]
|
||||||
|
self.paraBox.setValue(box, path)
|
||||||
|
self.paraBox.show_parameter(directory)
|
||||||
|
|
||||||
def remove_event(self, event):
|
def remove_event(self, event):
|
||||||
qmb = QMessageBox(self, icon=QMessageBox.Question,
|
qmb = QMessageBox(self, icon=QMessageBox.Question,
|
||||||
@ -1297,11 +1294,6 @@ class MainWindow(QMainWindow):
|
|||||||
'''
|
'''
|
||||||
qcb = QComboBox()
|
qcb = QComboBox()
|
||||||
palette = qcb.palette()
|
palette = qcb.palette()
|
||||||
# change highlight color:
|
|
||||||
# palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Highlight,
|
|
||||||
# QtGui.QBrush(QtGui.QColor(0,0,127,127)))
|
|
||||||
# palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Highlight,
|
|
||||||
# QtGui.QBrush(QtGui.QColor(0,0,127,127)))
|
|
||||||
qcb.setPalette(palette)
|
qcb.setPalette(palette)
|
||||||
return qcb
|
return qcb
|
||||||
|
|
||||||
@ -1376,15 +1368,40 @@ class MainWindow(QMainWindow):
|
|||||||
:type: str
|
:type: str
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# if pick widget is open, refresh tooltips as well
|
self.refresh_tooltips()
|
||||||
|
|
||||||
|
if not eventBox:
|
||||||
|
eventBox = self.eventBox
|
||||||
|
self.setup_eventBox(eventBox)
|
||||||
|
|
||||||
|
current_event = self.get_current_event()
|
||||||
|
eventBox.clear()
|
||||||
|
model = eventBox.model()
|
||||||
|
|
||||||
|
plmax = self.get_max_path_length()
|
||||||
|
index = eventBox.currentIndex()
|
||||||
|
|
||||||
|
for id, event in enumerate(self.project.eventlist):
|
||||||
|
event_data = self.collect_event_data(event, plmax)
|
||||||
|
itemlist = self.create_event_items(event_data)
|
||||||
|
self.setItemColor(itemlist, id, event, current_event)
|
||||||
|
|
||||||
|
if event.isTestEvent() and select_events == 'ref' or self.isEmpty(event.path):
|
||||||
|
self.disable_items(itemlist)
|
||||||
|
|
||||||
|
model.appendRow(itemlist)
|
||||||
|
self.validate_event_path(event.path, id)
|
||||||
|
|
||||||
|
eventBox.setCurrentIndex(index)
|
||||||
|
self.refreshRefTestButtons()
|
||||||
|
|
||||||
|
def refresh_tooltips(self):
|
||||||
if self.apw:
|
if self.apw:
|
||||||
self.apw.refresh_tooltips()
|
self.apw.refresh_tooltips()
|
||||||
if hasattr(self, 'cmpw'):
|
if hasattr(self, 'cmpw'):
|
||||||
self.cmpw.refresh_tooltips()
|
self.cmpw.refresh_tooltips()
|
||||||
|
|
||||||
if not eventBox:
|
def setup_eventBox(self, eventBox):
|
||||||
eventBox = self.eventBox
|
|
||||||
index = eventBox.currentIndex()
|
|
||||||
tv = QtWidgets.QTableView()
|
tv = QtWidgets.QTableView()
|
||||||
header = tv.horizontalHeader()
|
header = tv.horizontalHeader()
|
||||||
header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
|
header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
|
||||||
@ -1392,136 +1409,107 @@ class MainWindow(QMainWindow):
|
|||||||
header.hide()
|
header.hide()
|
||||||
tv.verticalHeader().hide()
|
tv.verticalHeader().hide()
|
||||||
tv.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
|
tv.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
|
||||||
|
|
||||||
current_event = self.get_current_event()
|
|
||||||
|
|
||||||
eventBox.setView(tv)
|
eventBox.setView(tv)
|
||||||
eventBox.clear()
|
|
||||||
model = eventBox.model()
|
|
||||||
plmax = 0
|
|
||||||
# set maximum length of path string
|
|
||||||
for event in self.project.eventlist:
|
|
||||||
pl = len(event.path)
|
|
||||||
if pl > plmax:
|
|
||||||
plmax = pl
|
|
||||||
|
|
||||||
for id, event in enumerate(self.project.eventlist):
|
def get_max_path_length(self):
|
||||||
event_path = event.path
|
return max(len(event.path) for event in self.project.eventlist)
|
||||||
#phaseErrors = {'P': self._inputs['timeerrorsP'],
|
|
||||||
# 'S': self._inputs['timeerrorsS']}
|
|
||||||
|
|
||||||
man_au_picks = {'manual': event.pylot_picks,
|
def collect_event_data(self, event, plmax):
|
||||||
'auto': event.pylot_autopicks}
|
data = {
|
||||||
npicks = {'manual': {'P': 0, 'S': 0},
|
'path': event.path,
|
||||||
'auto': {'P': 0, 'S': 0}}
|
'picks': self.get_picks(event),
|
||||||
npicks_total = {'manual': {'P': 0, 'S': 0},
|
'is_ref': event.isRefEvent(),
|
||||||
'auto': {'P': 0, 'S': 0}}
|
'is_test': event.isTestEvent(),
|
||||||
|
'time': None,
|
||||||
|
'lat': None,
|
||||||
|
'lon': None,
|
||||||
|
'depth': None,
|
||||||
|
'localmag': None,
|
||||||
|
'momentmag': None,
|
||||||
|
'notes': event.notes,
|
||||||
|
'dirty': event.dirty,
|
||||||
|
'plmax': plmax,
|
||||||
|
}
|
||||||
|
|
||||||
for ma in man_au_picks.keys():
|
if event.origins:
|
||||||
if man_au_picks[ma]:
|
origin = event.origins[0]
|
||||||
for picks in man_au_picks[ma].values():
|
data['time'] = origin.time + 0 # add 0 to avoid exception for time = 0s
|
||||||
for phasename, pick in picks.items():
|
data['lat'] = origin.latitude
|
||||||
if not type(pick) in [dict, AttribDict]:
|
data['lon'] = origin.longitude
|
||||||
continue
|
data['depth'] = origin.depth
|
||||||
|
|
||||||
|
if event.magnitudes:
|
||||||
|
data['momentmag'] = '{:.1f}'.format(event.magnitudes[0].mag)
|
||||||
|
data['localmag'] = '{:.1f}'.format(event.magnitudes[1].mag) if len(event.magnitudes) > 1 else ' '
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
def get_picks(self, event):
|
||||||
|
man_au_picks = {'manual': event.pylot_picks, 'auto': event.pylot_autopicks}
|
||||||
|
npicks = {'manual': {'P': 0, 'S': 0}, 'auto': {'P': 0, 'S': 0}}
|
||||||
|
npicks_total = {'manual': {'P': 0, 'S': 0}, 'auto': {'P': 0, 'S': 0}}
|
||||||
|
|
||||||
|
for ma, picks in man_au_picks.items():
|
||||||
|
if picks:
|
||||||
|
for pick_values in picks.values():
|
||||||
|
for phasename, pick in pick_values.items():
|
||||||
|
if isinstance(pick, (dict, AttribDict)):
|
||||||
phase_ID = identifyPhaseID(phasename)
|
phase_ID = identifyPhaseID(phasename)
|
||||||
if not phase_ID in npicks[ma].keys():
|
if phase_ID in npicks[ma]:
|
||||||
continue
|
|
||||||
if pick.get('spe'):
|
if pick.get('spe'):
|
||||||
npicks[ma][phase_ID] += 1
|
npicks[ma][phase_ID] += 1
|
||||||
npicks_total[ma][phase_ID] += 1
|
npicks_total[ma][phase_ID] += 1
|
||||||
|
|
||||||
event_ref = event.isRefEvent()
|
return npicks, npicks_total
|
||||||
event_test = event.isTestEvent()
|
|
||||||
|
|
||||||
time = lat = lon = depth = localmag = None
|
def create_event_items(self, data):
|
||||||
if len(event.origins) == 1:
|
items = [
|
||||||
origin = event.origins[0]
|
self.create_standard_item(data['path'], data['plmax'],
|
||||||
time = origin.time + 0 # add 0 because there was an exception for time = 0s
|
icon=self.style().standardIcon(QStyle.SP_DirOpenIcon)),
|
||||||
lat = origin.latitude
|
self.create_standard_item(data['time'].strftime("%Y-%m-%d %H:%M:%S") if data['time'] else ''),
|
||||||
lon = origin.longitude
|
self.create_standard_item(data['lat']),
|
||||||
depth = origin.depth
|
self.create_standard_item(data['lon']),
|
||||||
if len(event.magnitudes): # if magnitude information exists, i.e., event.magnitudes has at least 1 entry
|
self.create_standard_item(data['depth']),
|
||||||
moment_magnitude = event.magnitudes[0]
|
self.create_standard_item(data['localmag']),
|
||||||
momentmag = '%4.1f' % moment_magnitude.mag
|
self.create_standard_item(data['momentmag']),
|
||||||
if len(event.magnitudes) > 1:
|
self.create_pick_item(data['picks'][0]['manual']),
|
||||||
local_magnitude = event.magnitudes[1]
|
self.create_pick_item(data['picks'][0]['auto']),
|
||||||
localmag = '%4.1f' % local_magnitude.mag
|
self.create_ref_test_item(data['is_ref'], 'ref'),
|
||||||
else:
|
self.create_ref_test_item(data['is_test'], 'test'),
|
||||||
localmag = ' '
|
self.create_standard_item(data['notes'])
|
||||||
|
]
|
||||||
|
|
||||||
else:
|
for item in items:
|
||||||
momentmag = ' '
|
|
||||||
localmag = ' '
|
|
||||||
|
|
||||||
# text = '{path:{plen}} | manual: [{p:3d}] | auto: [{a:3d}]'
|
|
||||||
# text = text.format(path=event_path,
|
|
||||||
# plen=plmax,
|
|
||||||
# p=event_npicks,
|
|
||||||
# a=event_nautopicks)
|
|
||||||
|
|
||||||
event_str = '{path:{plen}}'.format(path=event_path, plen=plmax)
|
|
||||||
if event.dirty:
|
|
||||||
event_str += '*'
|
|
||||||
item_path = QStandardItem(event_str)
|
|
||||||
item_time = QStandardItem('{}'.format(time.strftime("%Y-%m-%d %H:%M:%S") if time else ''))
|
|
||||||
item_lat = QStandardItem('{}'.format(lat))
|
|
||||||
item_lon = QStandardItem('{}'.format(lon))
|
|
||||||
item_depth = QStandardItem('{}'.format(depth))
|
|
||||||
item_localmag = QStandardItem('{}'.format(localmag))
|
|
||||||
item_momentmag = QStandardItem('{}'.format(momentmag))
|
|
||||||
|
|
||||||
item_nmp = QStandardItem()
|
|
||||||
item_nap = QStandardItem()
|
|
||||||
item_nmp.setIcon(self.manupicksicon_small)
|
|
||||||
item_nap.setIcon(self.autopicksicon_small)
|
|
||||||
|
|
||||||
for picktype, item_np in [('manual', item_nmp), ('auto', item_nap)]:
|
|
||||||
npicks_str = f"{npicks[picktype]['P']}|{npicks[picktype]['S']}"
|
|
||||||
#npicks_str += f"({npicks_total[picktype]['P']}/{npicks_total[picktype]['S']})"
|
|
||||||
item_np.setText(npicks_str)
|
|
||||||
|
|
||||||
item_ref = QStandardItem() # str(event_ref))
|
|
||||||
item_test = QStandardItem() # str(event_test))
|
|
||||||
if event_ref:
|
|
||||||
item_ref.setBackground(self._ref_test_colors['ref'])
|
|
||||||
if event_test:
|
|
||||||
item_test.setBackground(self._ref_test_colors['test'])
|
|
||||||
item_notes = QStandardItem(event.notes)
|
|
||||||
|
|
||||||
openIcon = self.style().standardIcon(QStyle.SP_DirOpenIcon)
|
|
||||||
item_path.setIcon(openIcon)
|
|
||||||
# if ref: set different color e.g.
|
|
||||||
# if event_ref:
|
|
||||||
# item.setBackground(self._colors['ref'])
|
|
||||||
# if event_test:
|
|
||||||
# itemt.setBackground(self._colors['test'])
|
|
||||||
# item.setForeground(QtGui.QColor('black'))
|
|
||||||
# font = item.font()
|
|
||||||
# font.setPointSize(10)
|
|
||||||
# item.setFont(font)
|
|
||||||
# item2.setForeground(QtGui.QColor('black'))
|
|
||||||
# item2.setFont(font)
|
|
||||||
itemlist = [item_path, item_time, item_lat, item_lon, item_depth,
|
|
||||||
item_localmag, item_momentmag, item_nmp, item_nap, item_ref, item_test, item_notes]
|
|
||||||
for item in itemlist:
|
|
||||||
item.setTextAlignment(Qt.AlignCenter)
|
item.setTextAlignment(Qt.AlignCenter)
|
||||||
if event_test and select_events == 'ref' or self.isEmpty(event_path):
|
if data['dirty'] and item == items[0]:
|
||||||
for item in itemlist:
|
item.setText(f"{item.text()}*")
|
||||||
|
|
||||||
|
return items
|
||||||
|
|
||||||
|
def create_standard_item(self, text, max_length=None, icon=None):
|
||||||
|
item = QStandardItem(f"{text:{max_length}}" if max_length else str(text))
|
||||||
|
if icon:
|
||||||
|
item.setIcon(icon)
|
||||||
|
return item
|
||||||
|
|
||||||
|
def create_pick_item(self, picks):
|
||||||
|
item = QStandardItem()
|
||||||
|
item.setText(f"{picks['P']}|{picks['S']}")
|
||||||
|
return item
|
||||||
|
|
||||||
|
def create_ref_test_item(self, condition, color_key):
|
||||||
|
item = QStandardItem()
|
||||||
|
if condition:
|
||||||
|
item.setBackground(self._ref_test_colors[color_key])
|
||||||
|
return item
|
||||||
|
|
||||||
|
def disable_items(self, items):
|
||||||
|
for item in items:
|
||||||
item.setEnabled(False)
|
item.setEnabled(False)
|
||||||
|
|
||||||
# item color
|
def validate_event_path(self, path, id):
|
||||||
self.setItemColor(itemlist, id, event, current_event)
|
if path != self.eventBox.itemText(id).split('*')[0].strip():
|
||||||
|
raise ValueError(f"Path mismatch creating eventbox. {path} unequal {self.eventBox.itemText(id)}")
|
||||||
model.appendRow(itemlist)
|
|
||||||
if not event.path == self.eventBox.itemText(id).split('*')[0].strip():
|
|
||||||
message = ('Path missmatch creating eventbox.\n'
|
|
||||||
'{} unequal {}.'
|
|
||||||
.format(event.path, self.eventBox.itemText(id)))
|
|
||||||
raise ValueError(message)
|
|
||||||
# not working with obspy events
|
|
||||||
# eventBox.setItemData(id, event)
|
|
||||||
eventBox.setCurrentIndex(index)
|
|
||||||
self.refreshRefTestButtons()
|
|
||||||
|
|
||||||
def isEmpty(self, event_path):
|
def isEmpty(self, event_path):
|
||||||
wf_stat = {True: 'processed',
|
wf_stat = {True: 'processed',
|
||||||
@ -1978,14 +1966,6 @@ class MainWindow(QMainWindow):
|
|||||||
'''
|
'''
|
||||||
Load waveform data corresponding to current selected event.
|
Load waveform data corresponding to current selected event.
|
||||||
'''
|
'''
|
||||||
# if self.fnames and self.okToContinue():
|
|
||||||
# self.setDirty(True)
|
|
||||||
# ans = self.data.setWFData(self.fnames)
|
|
||||||
# elif self.fnames is None and self.okToContinue():
|
|
||||||
# ans = self.data.setWFData(self.getWFFnames())
|
|
||||||
# else:
|
|
||||||
# ans = False
|
|
||||||
|
|
||||||
settings = QSettings()
|
settings = QSettings()
|
||||||
# process application events to wait for event items to appear in event box
|
# process application events to wait for event items to appear in event box
|
||||||
QApplication.processEvents()
|
QApplication.processEvents()
|
||||||
@ -2033,21 +2013,6 @@ class MainWindow(QMainWindow):
|
|||||||
eventpath_dmt = os.path.join(eventpath, wftype)
|
eventpath_dmt = os.path.join(eventpath, wftype)
|
||||||
self.fnames = [os.path.join(eventpath_dmt, filename) for filename in os.listdir(eventpath_dmt)]
|
self.fnames = [os.path.join(eventpath_dmt, filename) for filename in os.listdir(eventpath_dmt)]
|
||||||
|
|
||||||
# def setWFstatus(self):
|
|
||||||
# '''
|
|
||||||
# show status of current data, can be either 'raw' or 'processed'
|
|
||||||
# :param status:
|
|
||||||
# :return:
|
|
||||||
# '''
|
|
||||||
# status = self.data.processed
|
|
||||||
# wf_stat_color = {True: 'green',
|
|
||||||
# False: 'black',
|
|
||||||
# None: None}
|
|
||||||
# wf_stat = {True: 'processed',
|
|
||||||
# False: 'raw',
|
|
||||||
# None: None}
|
|
||||||
# self.dataPlot.setQCboxItem(wf_stat[status])
|
|
||||||
|
|
||||||
def check_plot_quantity(self):
|
def check_plot_quantity(self):
|
||||||
"""
|
"""
|
||||||
Check the amount of samples to be plotted and ask user to reduce the amount if it is too large.
|
Check the amount of samples to be plotted and ask user to reduce the amount if it is too large.
|
||||||
@ -2067,24 +2032,6 @@ class MainWindow(QMainWindow):
|
|||||||
self.update_status('Dataset is very large. Using fast plotting method (MIN/MAX)', 10000)
|
self.update_status('Dataset is very large. Using fast plotting method (MIN/MAX)', 10000)
|
||||||
settings.sync()
|
settings.sync()
|
||||||
return True
|
return True
|
||||||
# nth_sample_new = int(np.ceil(npts/npts_max))
|
|
||||||
# message = "You are about to plot a huge dataset with {npts} datapoints. With a current setting of " \
|
|
||||||
# "nth_sample = {nth_sample} a total of {npts2plot} points will be plotted which is more " \
|
|
||||||
# "than the maximum setting of {npts_max}. " \
|
|
||||||
# "PyLoT recommends to raise nth_sample from {nth_sample} to {nth_sample_new}. Do you want "\
|
|
||||||
# "to change nth_sample to {nth_sample_new} now?"
|
|
||||||
#
|
|
||||||
# ans = QMessageBox.question(self, self.tr("Optimize plot performance..."),
|
|
||||||
# self.tr(message.format(npts=npts,
|
|
||||||
# nth_sample=nth_sample,
|
|
||||||
# npts_max=npts_max,
|
|
||||||
# nth_sample_new=nth_sample_new,
|
|
||||||
# npts2plot=npts2plot)),
|
|
||||||
# QMessageBox.Yes | QMessageBox.No,
|
|
||||||
# QMessageBox.Yes)
|
|
||||||
# if ans == QMessageBox.Yes:
|
|
||||||
# settings.setValue("nth_sample", nth_sample_new)
|
|
||||||
# settings.sync()
|
|
||||||
|
|
||||||
def get_npts_to_plot(self):
|
def get_npts_to_plot(self):
|
||||||
if not hasattr(self.data, 'wfdata'):
|
if not hasattr(self.data, 'wfdata'):
|
||||||
@ -2334,20 +2281,14 @@ class MainWindow(QMainWindow):
|
|||||||
def plotZ(self):
|
def plotZ(self):
|
||||||
self.setComponent('Z')
|
self.setComponent('Z')
|
||||||
self.plotWaveformDataThread()
|
self.plotWaveformDataThread()
|
||||||
# self.drawPicks()
|
|
||||||
# self.draw()
|
|
||||||
|
|
||||||
def plotN(self):
|
def plotN(self):
|
||||||
self.setComponent('N')
|
self.setComponent('N')
|
||||||
self.plotWaveformDataThread()
|
self.plotWaveformDataThread()
|
||||||
# self.drawPicks()
|
|
||||||
# self.draw()
|
|
||||||
|
|
||||||
def plotE(self):
|
def plotE(self):
|
||||||
self.setComponent('E')
|
self.setComponent('E')
|
||||||
self.plotWaveformDataThread()
|
self.plotWaveformDataThread()
|
||||||
# self.drawPicks()
|
|
||||||
# self.draw()
|
|
||||||
|
|
||||||
def pushFilterWF(self, param_args):
|
def pushFilterWF(self, param_args):
|
||||||
self.get_data().filterWFData(param_args)
|
self.get_data().filterWFData(param_args)
|
||||||
@ -2393,8 +2334,6 @@ class MainWindow(QMainWindow):
|
|||||||
self.get_data().resetWFData()
|
self.get_data().resetWFData()
|
||||||
if plot:
|
if plot:
|
||||||
self.plotWaveformDataThread(filter=False)
|
self.plotWaveformDataThread(filter=False)
|
||||||
# self.drawPicks()
|
|
||||||
# self.draw()
|
|
||||||
|
|
||||||
def getAutoFilteroptions(self, phase):
|
def getAutoFilteroptions(self, phase):
|
||||||
return getAutoFilteroptions(phase, self._inputs)
|
return getAutoFilteroptions(phase, self._inputs)
|
||||||
@ -2426,20 +2365,8 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
def getFilterOptions(self):
|
def getFilterOptions(self):
|
||||||
return self.filteroptions
|
return self.filteroptions
|
||||||
# try:
|
|
||||||
# return self.filteroptions[self.getSeismicPhase()]
|
|
||||||
# except AttributeError as e:
|
|
||||||
# print(e)
|
|
||||||
# return FilterOptions(None, None, None)
|
|
||||||
|
|
||||||
def getFilters(self):
|
def setFilterOptions(self, filterOptions):
|
||||||
return self.filteroptions
|
|
||||||
|
|
||||||
def setFilterOptions(self, filterOptions): # , seismicPhase=None):
|
|
||||||
# if seismicPhase is None:
|
|
||||||
# self.getFilterOptions()[self.getSeismicPhase()] = filterOptions
|
|
||||||
# else:
|
|
||||||
# self.getFilterOptions()[seismicPhase] = filterOptions
|
|
||||||
self.filterOptions = filterOptions
|
self.filterOptions = filterOptions
|
||||||
filterP = filterOptions['P']
|
filterP = filterOptions['P']
|
||||||
filterS = filterOptions['S']
|
filterS = filterOptions['S']
|
||||||
@ -2468,28 +2395,6 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
self.checkFilterOptions()
|
self.checkFilterOptions()
|
||||||
|
|
||||||
# def updateFilterOptions(self):
|
|
||||||
# try:
|
|
||||||
# settings = QSettings()
|
|
||||||
# if settings.value("filterdefaults",
|
|
||||||
# None) is None and not self.getFilters():
|
|
||||||
# for key, value in FILTERDEFAULTS.items():
|
|
||||||
# self.setFilterOptions(FilterOptions(**value), key)
|
|
||||||
# elif settings.value("filterdefaults", None) is not None:
|
|
||||||
# for key, value in settings.value("filterdefaults"):
|
|
||||||
# self.setFilterOptions(FilterOptions(**value), key)
|
|
||||||
# except Exception as e:
|
|
||||||
# self.update_status('Error ...')
|
|
||||||
# emsg = QErrorMessage(self)
|
|
||||||
# emsg.showMessage('Error: {0}'.format(e))
|
|
||||||
# else:
|
|
||||||
# self.update_status('Filter loaded ... '
|
|
||||||
# '[{0}: {1} Hz]'.format(
|
|
||||||
# self.getFilterOptions().getFilterType(),
|
|
||||||
# self.getFilterOptions().getFreq()))
|
|
||||||
# if self.filterActionP.isChecked() or self.filterActionS.isChecked():
|
|
||||||
# self.filterWaveformData()
|
|
||||||
|
|
||||||
def getSeismicPhase(self):
|
def getSeismicPhase(self):
|
||||||
return self.seismicPhase
|
return self.seismicPhase
|
||||||
|
|
||||||
@ -2515,11 +2420,6 @@ class MainWindow(QMainWindow):
|
|||||||
def alterPhase(self):
|
def alterPhase(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def setSeismicPhase(self, phase):
|
|
||||||
self.seismicPhase = self.seismicPhaseButtonGroup.getValue()
|
|
||||||
self.update_status('Seismic phase changed to '
|
|
||||||
'{0}'.format(self.getSeismicPhase()))
|
|
||||||
|
|
||||||
def scrollPlot(self, gui_event):
|
def scrollPlot(self, gui_event):
|
||||||
'''
|
'''
|
||||||
Function connected to mouse wheel scrolling inside WFdataPlot.
|
Function connected to mouse wheel scrolling inside WFdataPlot.
|
||||||
@ -2935,11 +2835,6 @@ class MainWindow(QMainWindow):
|
|||||||
automanu[type](station=station, pick=picks)
|
automanu[type](station=station, pick=picks)
|
||||||
return rval
|
return rval
|
||||||
|
|
||||||
def deletePicks(self, station, deleted_pick, type):
|
|
||||||
deleted_pick['station'] = station
|
|
||||||
self.addPicks(station, {}, type=type)
|
|
||||||
self.log_deleted_picks([deleted_pick])
|
|
||||||
|
|
||||||
def log_deleted_picks(self, deleted_picks, event_path=None):
|
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
|
||||||
@ -3075,10 +2970,6 @@ class MainWindow(QMainWindow):
|
|||||||
elif phaseID == 'S':
|
elif phaseID == 'S':
|
||||||
quality = getQualityFromUncertainty(picks['spe'], self._inputs['timeerrorsS'])
|
quality = getQualityFromUncertainty(picks['spe'], self._inputs['timeerrorsS'])
|
||||||
|
|
||||||
# quality = getPickQuality(self.get_data().getWFData(),
|
|
||||||
# stat_picks, self._inputs, phaseID,
|
|
||||||
# compclass)
|
|
||||||
|
|
||||||
if not picks['mpp']: continue
|
if not picks['mpp']: continue
|
||||||
|
|
||||||
mpp = picks['mpp'] - stime
|
mpp = picks['mpp'] - stime
|
||||||
@ -3628,19 +3519,6 @@ class MainWindow(QMainWindow):
|
|||||||
def check4Loc(self):
|
def check4Loc(self):
|
||||||
return self.picksNum() >= 4
|
return self.picksNum() >= 4
|
||||||
|
|
||||||
# def check4Comparison(self):
|
|
||||||
# mpicks = self.getPicks()
|
|
||||||
# apicks = self.getPicks('auto')
|
|
||||||
# for station, phases in mpicks.items():
|
|
||||||
# try:
|
|
||||||
# aphases = apicks[station]
|
|
||||||
# for phase in phases.keys():
|
|
||||||
# if phase in aphases.keys():
|
|
||||||
# return True
|
|
||||||
# except KeyError:
|
|
||||||
# continue
|
|
||||||
# return False
|
|
||||||
|
|
||||||
def picksNum(self, type='manual'):
|
def picksNum(self, type='manual'):
|
||||||
num = 0
|
num = 0
|
||||||
for phases in self.getPicks(type).values():
|
for phases in self.getPicks(type).values():
|
||||||
@ -3681,16 +3559,6 @@ class MainWindow(QMainWindow):
|
|||||||
def show_event_information(self):
|
def show_event_information(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def createNewEvent(self):
|
|
||||||
if self.okToContinue():
|
|
||||||
new = NewEventDlg()
|
|
||||||
if new.exec_() != QDialog.Rejected:
|
|
||||||
evtpar = new.getValues()
|
|
||||||
cinfo = create_creation_info(agency_id=self.agency)
|
|
||||||
event = create_event(evtpar['origintime'], cinfo)
|
|
||||||
self.data = Data(self, evtdata=event)
|
|
||||||
self.setDirty(True)
|
|
||||||
|
|
||||||
def createNewProject(self):
|
def createNewProject(self):
|
||||||
'''
|
'''
|
||||||
Create new project file.
|
Create new project file.
|
||||||
@ -3834,16 +3702,6 @@ class MainWindow(QMainWindow):
|
|||||||
self.dirty = value
|
self.dirty = value
|
||||||
self.fill_eventbox()
|
self.fill_eventbox()
|
||||||
|
|
||||||
def closeEvent(self, event):
|
|
||||||
if self.okToContinue():
|
|
||||||
if hasattr(self, 'logwidget'):
|
|
||||||
self.logwidget.close()
|
|
||||||
event.accept()
|
|
||||||
else:
|
|
||||||
event.ignore()
|
|
||||||
# self.closing.emit()
|
|
||||||
# QMainWindow.closeEvent(self, event)
|
|
||||||
|
|
||||||
def setParameter(self, checked=0, show=True):
|
def setParameter(self, checked=0, show=True):
|
||||||
if checked: pass # dummy argument to receive trigger signal (checked) if called by QAction
|
if checked: pass # dummy argument to receive trigger signal (checked) if called by QAction
|
||||||
if not self.paraBox:
|
if not self.paraBox:
|
||||||
@ -4095,8 +3953,6 @@ def create_window():
|
|||||||
app.setOrganizationDomain("rub.de")
|
app.setOrganizationDomain("rub.de")
|
||||||
app.setApplicationName("PyLoT")
|
app.setApplicationName("PyLoT")
|
||||||
app.references = set()
|
app.references = set()
|
||||||
# app.references.add(window)
|
|
||||||
# window.show()
|
|
||||||
return app, app_created
|
return app, app_created
|
||||||
|
|
||||||
|
|
||||||
@ -4104,7 +3960,6 @@ def main(project_filename=None, pylot_infile=None, reset_qsettings=False):
|
|||||||
|
|
||||||
# create the Qt application
|
# create the Qt application
|
||||||
pylot_app, app_created = create_window()
|
pylot_app, app_created = create_window()
|
||||||
# pylot_app = QApplication(sys.argv)
|
|
||||||
pixmap = QPixmap(":/splash/splash.png")
|
pixmap = QPixmap(":/splash/splash.png")
|
||||||
splash = QSplashScreen(pixmap)
|
splash = QSplashScreen(pixmap)
|
||||||
splash.show()
|
splash.show()
|
||||||
|
Loading…
Reference in New Issue
Block a user