diff --git a/QtPyLoT.py b/QtPyLoT.py index 7a18a9d1..34a7e22f 100755 --- a/QtPyLoT.py +++ b/QtPyLoT.py @@ -81,7 +81,7 @@ from pylot.core.util.widgets import FilterOptionsDialog, NewEventDlg, \ getDataType, ComparisonDialog, TuneAutopicker, PylotParaBox from pylot.core.util.map_projection import map_projection from pylot.core.util.structure import DATASTRUCTURE -from pylot.core.util.thread import AutoPickThread, Thread +from pylot.core.util.thread import AutoPickThread, Thread, MultiThread from pylot.core.util.version import get_git_version as _getVersionString if sys.version_info.major == 3: @@ -1838,6 +1838,36 @@ class MainWindow(QMainWindow): self.canvas_dict[key] = FigureCanvas(self.fig_dict[key]) self.tap.fill_tabs(picked=True) + # def autoPick(self): + # self.autosave = QFileDialog().getExistingDirectory(caption='Select autoPyLoT output') + # if not os.path.exists(self.autosave): + # QMessageBox.warning(self, "PyLoT Warning", + # "No autoPyLoT output declared!") + # return + # self.listWidget = QListWidget() + # self.setDirty(True) + # self.logDockWidget = QDockWidget("AutoPickLog", self) + # self.logDockWidget.setObjectName("LogDockWidget") + # self.logDockWidget.setAllowedAreas( + # Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) + # self.logDockWidget.setWidget(self.listWidget) + # self.addDockWidget(Qt.LeftDockWidgetArea, self.logDockWidget) + # self.addListItem('Loading default values from PyLoT-input file %s' + # % self.infile) + # autopick_parameter = self._inputs + # self.addListItem(str(autopick_parameter)) + # receventid = self.get_current_event_path() + # self.thread = AutoPickThread(parent=self, + # func=autoPyLoT, + # infile=self.infile, + # fnames=self.fnames, + # eventid=receventid, + # savepath=self.autosave) + + # self.thread.message.connect(self.addListItem) + # self.thread.start() + # self.thread.finished.connect(self.finalizeAutoPick) + def autoPick(self): self.autosave = QFileDialog().getExistingDirectory(caption='Select autoPyLoT output') if not os.path.exists(self.autosave): @@ -1852,26 +1882,44 @@ class MainWindow(QMainWindow): Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) self.logDockWidget.setWidget(self.listWidget) self.addDockWidget(Qt.LeftDockWidgetArea, self.logDockWidget) - self.addListItem('Loading default values from PyLoT-input file %s' - % self.infile) - autopick_parameter = self._inputs - self.addListItem(str(autopick_parameter)) - receventid = self.get_current_event_path() - self.thread = AutoPickThread(parent=self, - func=autoPyLoT, - infile=self.infile, - fnames=self.fnames, - eventid=receventid, - savepath=self.autosave) + # self.addListItem('Loading default values from PyLoT-input file %s' + # % self.infile) - self.thread.message.connect(self.addListItem) - self.thread.start() - self.thread.finished.connect(self.finalizeAutoPick) + stations = [] + # catch all station names + for trace in self.data.getWFData(): + station = trace.stats.station + if not station in stations: + stations.append(station) + + mp_args = [] + # create input_dict for each station in a list for multiprocessing.Pool iteration + for station in stations: + args = {'parameter': self._inputs, + 'station': station, + 'fnames': 'None', + 'eventid': self.get_current_event_path (), + 'iplot': 0, + 'fig_dict': None, + 'locflag': 0} + mp_args.append(args) + + self.mp_thread = MultiThread (self, autoPyLoT, args=mp_args, + ncores=0, + progressText='Picking event...', + pb_widget=None, + redirect_stdout=True) + + self.addListItem(str(self._inputs)) + + self.mp_thread.message.connect(self.addListItem) + self.mp_thread.start() + self.mp_thread.finished.connect(self.finalizeAutoPick) def finalizeAutoPick(self): self.drawPicks(picktype='auto') self.draw() - self.thread.quit() + self.mp_thread.quit() def addPicks(self, station, picks, type='manual'): stat_picks = self.getPicksOnStation(station, type) @@ -2218,7 +2266,7 @@ class MainWindow(QMainWindow): # generate delete icon del_icon = QIcon() del_icon.addPixmap(QPixmap(':/icons/delete.png')) - + # remove old table if hasattr(self, 'event_table'): self.event_table.setParent(None) diff --git a/autoPyLoT.py b/autoPyLoT.py index a02ff306..6f39424e 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -66,6 +66,8 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even station = input_dict['station'] if input_dict.has_key('fnames'): fnames = input_dict['fnames'] + if input_dict.has_key('eventid'): + eventid = input_dict['eventid'] if input_dict.has_key('iplot'): iplot = input_dict['iplot'] if input_dict.has_key('locflag'): @@ -155,7 +157,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even events = [] events.append(os.path.join(datapath, parameter['database'], - parameter['eventID'])) + eventid)) if not events: print('autoPyLoT: No events given. Return!') diff --git a/pylot/RELEASE-VERSION b/pylot/RELEASE-VERSION index 63b48cb8..518a60d7 100644 --- a/pylot/RELEASE-VERSION +++ b/pylot/RELEASE-VERSION @@ -1 +1 @@ -f86f-dirty +f135-dirty diff --git a/pylot/core/util/thread.py b/pylot/core/util/thread.py index 5928ace3..26c0c508 100644 --- a/pylot/core/util/thread.py +++ b/pylot/core/util/thread.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- import sys, os +import multiprocessing from PySide.QtCore import QThread, Signal, Qt -from PySide.QtGui import QDialog, QProgressBar, QLabel, QHBoxLayout +from PySide.QtGui import QDialog, QProgressBar, QLabel, QHBoxLayout, QPushButton class AutoPickThread(QThread): @@ -69,6 +70,76 @@ class Thread(QThread): print('Exception: {}, file: {}, line: {}'.format(exc_type, fname, exc_tb.tb_lineno)) sys.stdout = sys.__stdout__ + # def __del__(self): + # self.wait() + + def showProgressbar(self): + if self.progressText: + + # generate widget if not given in init + if not self.pb_widget: + self.pb_widget = QDialog(self.parent()) + self.pb_widget.setWindowFlags(Qt.SplashScreen) + self.pb_widget.setModal(True) + + # add button + delete_button = QPushButton('X') + delete_button.clicked.connect(self.exit) + hl = QHBoxLayout() + pb = QProgressBar() + pb.setRange(0, 0) + hl.addWidget(pb) + hl.addWidget(QLabel(self.progressText)) + hl.addWidget(delete_button) + self.pb_widget.setLayout(hl) + self.pb_widget.show() + + def hideProgressbar(self): + if self.pb_widget: + self.pb_widget.hide() + + def write(self, text): + self.message.emit(text) + + def flush(self): + pass + + +class MultiThread(QThread): + finished = Signal(str) + message = Signal(str) + + def __init__(self, parent, func, args, ncores=0, + progressText=None, pb_widget=None, redirect_stdout=False): + QThread.__init__(self, parent) + self.func = func + self.args = args + self.ncores = ncores + self.progressText = progressText + self.pb_widget = pb_widget + self.redirect_stdout = redirect_stdout + self.finished.connect(self.hideProgressbar) + self.showProgressbar() + + def run(self): + # if self.redirect_stdout: + # sys.stdout = self + # #try: + if not self.ncores: + self.ncores = multiprocessing.cpu_count() + pool = multiprocessing.Pool(self.ncores) + self.data = pool.map_async(self.func, self.args, callback=self.emitDone) + #self.data = pool.apply_async(self.func, self.shotlist, callback=self.emitDone) #emit each time returned + pool.close() + self._executed = True + # except Exception as e: + # self._executed = False + # self._executedError = e + # exc_type, exc_obj, exc_tb = sys.exc_info() + # fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] + # print('Exception: {}, file: {}, line: {}'.format(exc_type, fname, exc_tb.tb_lineno)) + sys.stdout = sys.__stdout__ + def __del__(self): self.wait() @@ -96,3 +167,7 @@ class Thread(QThread): def flush(self): pass + def emitDone(self, result): + print('emitDone!') + self.finished.emit('Done thread!') + self.hideProgressbar()