diff --git a/QtPyLoT.py b/QtPyLoT.py index d8ea085b..51e3dd93 100755 --- a/QtPyLoT.py +++ b/QtPyLoT.py @@ -55,9 +55,9 @@ except ImportError: from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar from matplotlib.figure import Figure -from pylot.core.analysis.magnitude import RichterMagnitude, MomentMagnitude +from pylot.core.analysis.magnitude import LocalMagnitude, MomentMagnitude from pylot.core.io.data import Data -from pylot.core.io.inputs import FilterOptions, AutoPickParameter +from pylot.core.io.inputs import FilterOptions, PylotParameter from autoPyLoT import autoPyLoT from pylot.core.pick.compare import Comparison from pylot.core.pick.utils import symmetrize_error @@ -73,7 +73,7 @@ from pylot.core.util.utils import fnConstructor, getLogin, \ from pylot.core.io.location import create_creation_info, create_event from pylot.core.util.widgets import FilterOptionsDialog, NewEventDlg, \ WaveformWidget, WaveformWidgetPG, PropertiesDlg, HelpForm, createAction, PickDlg, \ - getDataType, ComparisonDialog, TuneAutopicker, AutoPickParaBox + 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 @@ -103,7 +103,7 @@ class MainWindow(QMainWindow): self.infile = infile[0] else: self.infile = infile - self._inputs = AutoPickParameter(infile) + self._inputs = PylotParameter(infile) self._props = None self.dirty = False @@ -799,7 +799,7 @@ class MainWindow(QMainWindow): self.paraBox.setValue(box, dirs[directory]) #show needed parameter in box self.paraBox.show_parameter(directory) - dirs_box = self.paraBox.get_groupbox_exclusive('Directories') + dirs_box = self.paraBox.get_groupbox_dialog('Directories') if not dirs_box.exec_(): return self.project.rootpath = dirs['rootpath'] @@ -2150,7 +2150,7 @@ class MainWindow(QMainWindow): # if not rest_flag: # raise ProcessingError('Restitution of waveform data failed!') if type == 'ML': - local_mag = RichterMagnitude(corr_wf, self.get_data().get_evt_data(), self.inputs.get('sstop'), verbosity = True) + local_mag = LocalMagnitude(corr_wf, self.get_data().get_evt_data(), self.inputs.get('sstop'), verbosity = True) return local_mag.updated_event() elif type == 'Mw': moment_mag = MomentMagnitude(corr_wf, self.get_data().get_evt_data(), self.inputs.get('vp'), self.inputs.get('Qp'), self.inputs.get('rho'), verbosity = True) @@ -2331,7 +2331,7 @@ class MainWindow(QMainWindow): def setParameter(self, show=True): if not self.paraBox: - self.paraBox = AutoPickParaBox(self._inputs) + self.paraBox = PylotParaBox(self._inputs) self.paraBox._apply.clicked.connect(self._setDirty) self.paraBox._okay.clicked.connect(self._setDirty) if show: diff --git a/autoPyLoT.py b/autoPyLoT.py index 0df1e2cb..66db76a6 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -16,9 +16,9 @@ import pylot.core.loc.focmec as focmec import pylot.core.loc.hash as hash import pylot.core.loc.nll as nll #from PySide.QtGui import QWidget, QInputDialog -from pylot.core.analysis.magnitude import MomentMagnitude, RichterMagnitude +from pylot.core.analysis.magnitude import MomentMagnitude, LocalMagnitude from pylot.core.io.data import Data -from pylot.core.io.inputs import AutoPickParameter +from pylot.core.io.inputs import PylotParameter from pylot.core.pick.autopick import autopickevent, iteratepicker from pylot.core.util.dataprocessing import restitute_data, read_metadata, \ remove_underscores @@ -35,7 +35,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even :param inputfile: path to the input file containing all parameter information for automatic picking (for formatting details, see. - `~pylot.core.io.inputs.AutoPickParameter` + `~pylot.core.io.inputs.PylotParameter` :type inputfile: str :return: @@ -71,13 +71,13 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even if not parameter: if inputfile: - parameter = AutoPickParameter(inputfile) + parameter = PylotParameter(inputfile) iplot = parameter['iplot'] else: print('No parameters set and no input file given. Choose either of both.') return else: - if not type(parameter) == AutoPickParameter: + if not type(parameter) == PylotParameter: print('Wrong input type for parameter: {}'.format(type(parameter))) return if inputfile: @@ -252,9 +252,9 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even for station, props in moment_mag.moment_props.items(): picks[station]['P'].update(props) evt = moment_mag.updated_event() - local_mag = RichterMagnitude(corr_dat, evt, - parameter.get('sstop'), True,\ - iplot) + local_mag = LocalMagnitude(corr_dat, evt, + parameter.get('sstop'), parameter.get('WAscaling'), \ + True, iplot) for station, amplitude in local_mag.amplitudes.items(): picks[station]['S']['Ao'] = amplitude.generic_amplitude evt = local_mag.updated_event() @@ -310,9 +310,9 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even for station, props in moment_mag.moment_props.items(): picks[station]['P'].update(props) evt = moment_mag.updated_event() - local_mag = RichterMagnitude(corr_dat, evt, - parameter.get('sstop'), True, \ - iplot) + local_mag = LocalMagnitude(corr_dat, evt, + parameter.get('sstop'), parameter.get('WAscaling'), \ + True, iplot) for station, amplitude in local_mag.amplitudes.items(): picks[station]['S']['Ao'] = amplitude.generic_amplitude evt = local_mag.updated_event() diff --git a/pylot/RELEASE-VERSION b/pylot/RELEASE-VERSION index a281ef17..6bf29797 100644 --- a/pylot/RELEASE-VERSION +++ b/pylot/RELEASE-VERSION @@ -1 +1 @@ -6feff-dirty +f91e1-dirty diff --git a/pylot/core/analysis/magnitude.py b/pylot/core/analysis/magnitude.py index 06b540a4..ff4dca18 100644 --- a/pylot/core/analysis/magnitude.py +++ b/pylot/core/analysis/magnitude.py @@ -38,10 +38,10 @@ class Magnitude(object): def __init__(self, stream, event, verbosity=False, iplot=0): self._type = "M" + self._stream = stream self._plot_flag = iplot self._verbosity = verbosity self._event = event - self._stream = stream self._magnitudes = dict() def __str__(self): @@ -136,7 +136,7 @@ class Magnitude(object): return None -class RichterMagnitude(Magnitude): +class LocalMagnitude(Magnitude): """ Method to derive peak-to-peak amplitude as seen on a Wood-Anderson- seismograph. Has to be derived from instrument corrected traces! @@ -153,10 +153,11 @@ class RichterMagnitude(Magnitude): _amplitudes = dict() - def __init__(self, stream, event, calc_win, verbosity=False, iplot=0): - super(RichterMagnitude, self).__init__(stream, event, verbosity, iplot) + def __init__(self, stream, event, calc_win, wascaling=None, verbosity=False, iplot=0): + super(LocalMagnitude, self).__init__(stream, event, verbosity, iplot) self._calc_win = calc_win + self._wascaling = wascaling self._type = 'ML' self.calc() @@ -168,6 +169,10 @@ class RichterMagnitude(Magnitude): def calc_win(self, value): self._calc_win = value + @property + def wascaling(self): + return self._wascaling + @property def amplitudes(self): return self._amplitudes @@ -251,10 +256,16 @@ class RichterMagnitude(Magnitude): self.event.amplitudes.append(amplitude) self.amplitudes = (station, amplitude) # using standard Gutenberg-Richter relation - # TODO make the ML calculation more flexible by allowing - # use of custom relation functions - magnitude = ope.StationMagnitude( - mag=np.log10(a0) + richter_magnitude_scaling(delta)) + # or scale WA amplitude with given scaling relation + if self.wascaling == None: + print("Calculating original Richter magnitude ...") + magnitude = ope.StationMagnitude(mag=np.log10(a0) \ + + richter_magnitude_scaling(delta)) + else: + print("Calculating scaled local magnitude ...") + magnitude = ope.StationMagnitude(mag=np.log10(a0) \ + + self.wascaling[0] * np.log10(delta) + self.wascaling[1] + * delta + self.wascaling[2]) magnitude.origin_id = self.origin_id magnitude.waveform_id = pick.waveform_id magnitude.amplitude_id = amplitude.resource_id diff --git a/pylot/core/io/default_parameters.py b/pylot/core/io/default_parameters.py index 563476b8..93d55ae4 100644 --- a/pylot/core/io/default_parameters.py +++ b/pylot/core/io/default_parameters.py @@ -277,13 +277,13 @@ defaults = {'rootpath': {'type': str, 'tooltip': 'maximum allowed deviation from Wadati-diagram', 'value': 1.0}, - 'WAscaling': {'type': float, - 'tooltip': 'Scaling relation of Wood-Anderson amplitude [nm]', - 'value': 1.0}, + 'WAscaling': {'type': (float, float, float), + 'tooltip': 'Scaling relation (log(Ao)+Alog(r)+Br+C) of Wood-Anderson amplitude Ao [nm]', + 'value': (1.0, 1.0, 1.0)}, - 'magscaling': {'type': float, + 'magscaling': {'type': (float, float), 'tooltip': 'Scaling relation for derived local magnitude [a*Ml+b]', - 'value': 1.0} + 'value': (1.0, 1.0)} } settings_main={ diff --git a/pylot/core/io/inputs.py b/pylot/core/io/inputs.py index cd62b96a..3653b828 100644 --- a/pylot/core/io/inputs.py +++ b/pylot/core/io/inputs.py @@ -4,9 +4,9 @@ from pylot.core.util.errors import ParameterError import default_parameters -class AutoPickParameter(object): +class PylotParameter(object): ''' - AutoPickParameters is a parameter type object capable to read and/or write + PylotParameter is a parameter type object capable to read and/or write parameter ASCII. :param fn str: Filename of the input file @@ -78,7 +78,7 @@ class AutoPickParameter(object): # String representation of the object def __repr__(self): - return "AutoPickParameter('%s')" % self.__filename + return "PylotParameter('%s')" % self.__filename # Boolean test def __nonzero__(self): diff --git a/pylot/core/io/phases.py b/pylot/core/io/phases.py index 54f30695..eda56cf7 100644 --- a/pylot/core/io/phases.py +++ b/pylot/core/io/phases.py @@ -8,7 +8,7 @@ import scipy.io as sio import warnings from obspy.core import UTCDateTime -from pylot.core.io.inputs import AutoPickParameter +from pylot.core.io.inputs import PylotParameter from pylot.core.io.location import create_arrival, create_event, \ create_magnitude, create_origin, create_pick from pylot.core.pick.utils import select_for_phase @@ -116,7 +116,7 @@ def picksdict_from_pilot(fn): picks = dict() phases_pilot = sio.loadmat(fn) stations = stations_from_pilot(phases_pilot['stat']) - params = AutoPickParameter(TIMEERROR_DEFAULTS) + params = PylotParameter(TIMEERROR_DEFAULTS) timeerrors = dict(P=params.get('timeerrorsP'), S=params.get('timeerrorsS')) for n, station in enumerate(stations): @@ -295,14 +295,14 @@ def reassess_pilot_db(root_dir, db_dir, out_dir=None, fn_param=None, verbosity=0 def reassess_pilot_event(root_dir, db_dir, event_id, out_dir=None, fn_param=None, verbosity=0): from obspy import read - from pylot.core.io.inputs import AutoPickParameter + from pylot.core.io.inputs import PylotParameter from pylot.core.pick.utils import earllatepicker if fn_param is None: import pylot.core.util.defaults as defaults fn_param = defaults.AUTOMATIC_DEFAULTS - default = AutoPickParameter(fn_param, verbosity) + default = PylotParameter(fn_param, verbosity) search_base = os.path.join(root_dir, db_dir, event_id) phases_file = glob.glob(os.path.join(search_base, 'PHASES.mat')) diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index 8f43444b..a8437763 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -11,7 +11,7 @@ function conglomerate utils. import matplotlib.pyplot as plt import numpy as np -from pylot.core.io.inputs import AutoPickParameter +from pylot.core.io.inputs import PylotParameter from pylot.core.pick.picker import AICPicker, PragPicker from pylot.core.pick.charfuns import CharacteristicFunction from pylot.core.pick.charfuns import HOScf, AICcf, ARZcf, ARHcf, AR3Ccf @@ -81,7 +81,7 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None): :param pickparam: container of picking parameters from input file, usually autoPyLoT.in - :type pickparam: AutoPickParameter + :type pickparam: PylotParameter :param verbose: :type verbose: bool diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index 905073e1..46fa699a 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -10,7 +10,7 @@ import re import warnings import subprocess from obspy import UTCDateTime, read -from pylot.core.io.inputs import AutoPickParameter +from pylot.core.io.inputs import PylotParameter def _pickle_method(m): @@ -497,7 +497,7 @@ def which(program, infile=None): bpath = os.path.join(os.path.expanduser('~'), '.pylot', infile) if os.path.exists(bpath): - nllocpath = ":" + AutoPickParameter(bpath).get('nllocbin') + nllocpath = ":" + PylotParameter(bpath).get('nllocbin') os.environ['PATH'] += nllocpath except ImportError as e: print(e.message) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 9a051139..8fa59b71 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -36,7 +36,7 @@ from PySide.QtCore import QSettings, Qt, QUrl, Signal, Slot from PySide.QtWebKit import QWebView from obspy import Stream, UTCDateTime from pylot.core.io.data import Data -from pylot.core.io.inputs import FilterOptions, AutoPickParameter +from pylot.core.io.inputs import FilterOptions, PylotParameter from pylot.core.pick.utils import getSNR, earllatepicker, getnoisewin, \ getResolutionWindow from pylot.core.pick.compare import Comparison @@ -1662,7 +1662,7 @@ class TuneAutopicker(QWidget): self.stb_names = ['aicARHfig', 'refSpick', 'el_S1pick', 'el_S2pick'] def add_parameters(self): - self.paraBox = AutoPickParaBox(self.parameter) + self.paraBox = PylotParaBox(self.parameter) self.paraBox.set_tune_mode(True) self.update_eventID() self.parameter_layout.addWidget(self.paraBox) @@ -1968,13 +1968,13 @@ class TuneAutopicker(QWidget): self.qmb.show() -class AutoPickParaBox(QtGui.QWidget): +class PylotParaBox(QtGui.QWidget): def __init__(self, parameter, parent=None): ''' Generate Widget containing parameters for automatic picking algorithm. :param: parameter - :type: AutoPickParameter (object) + :type: PylotParameter (object) ''' QtGui.QWidget.__init__(self, parent) @@ -1987,6 +1987,7 @@ class AutoPickParaBox(QtGui.QWidget): self.labels = {} self.boxes = {} self.groupboxes = {} + self._exclusive_widgets = [] self._init_sublayouts() self.setLayout(self.layout) self.add_main_parameters_tab() @@ -2034,7 +2035,7 @@ class AutoPickParaBox(QtGui.QWidget): def _create_advanced_cb(self): self._advanced_cb = QtGui.QCheckBox('Enable Advanced Settings') - self._advanced_layout.addWidget(self._advanced_cb) + self._advanced_layout.insertWidget(0, self._advanced_cb) self._advanced_cb.toggled.connect(self._toggle_advanced_settings) def _toggle_advanced_settings(self): @@ -2140,13 +2141,13 @@ class AutoPickParaBox(QtGui.QWidget): def add_special_pick_parameters_tab(self): self.add_to_layout(self._advanced_layout, 'Z-component', - self.parameter.get_special_para_names()['z'], 0) + self.parameter.get_special_para_names()['z'], 1) self.add_to_layout(self._advanced_layout, 'H-components', - self.parameter.get_special_para_names()['h'], 1) + self.parameter.get_special_para_names()['h'], 2) self.add_to_layout(self._advanced_layout, 'First-motion picker', - self.parameter.get_special_para_names()['fm'], 2) + self.parameter.get_special_para_names()['fm'], 3) self.add_to_layout(self._advanced_layout, 'Quality assessment', - self.parameter.get_special_para_names()['quality'], 3) + self.parameter.get_special_para_names()['quality'], 4) self.add_tab(self._advanced_layout, 'Advanced Settings') # def gen_h_seperator(self): @@ -2168,20 +2169,29 @@ class AutoPickParaBox(QtGui.QWidget): layout.insertWidget(position, groupbox) def get_groupbox_exclusive(self, name): + widget = QtGui.QWidget(self, 1) + layout = QtGui.QVBoxLayout() + widget.setLayout(layout) + layout.addWidget(self.groupboxes[name]) + self._exclusive_widgets.append(widget) + return widget + + def get_groupbox_dialog(self, name): + widget = self.get_groupbox_exclusive(name) dialog = QtGui.QDialog(self.parent()) - buttonbox = QtGui.QDialogButtonBox(QDialogButtonBox.Ok | - QDialogButtonBox.Cancel) - self._exclusive_dialog = dialog layout = QtGui.QVBoxLayout() dialog.setLayout(layout) - layout.addWidget(self.groupboxes[name]) - layout.addWidget(buttonbox) + buttonbox = QtGui.QDialogButtonBox(QDialogButtonBox.Ok | + QDialogButtonBox.Cancel) buttonbox.accepted.connect(dialog.accept) buttonbox.accepted.connect(self.refresh) buttonbox.accepted.connect(self.params_from_gui) buttonbox.rejected.connect(dialog.reject) buttonbox.rejected.connect(self.refresh) buttonbox.rejected.connect(self.params_to_gui) + layout.addWidget(widget) + layout.addWidget(buttonbox) + self._exclusive_dialog = dialog return dialog def add_to_layout(self, layout, name, items, position): @@ -2342,6 +2352,7 @@ class AutoPickParaBox(QtGui.QWidget): self.show_parameter() if hasattr(self, '_exclusive_dialog'): self._exclusive_dialog.close() + self._exclusive_widgets = [] QtGui.QWidget.show(self) def _warn(self, message): @@ -2510,7 +2521,7 @@ class InputsTab(PropTab): return values def resetValues(self, infile): - para = AutoPickParameter(infile) + para = PylotParameter(infile) datstruct = para.get('datastructure') if datstruct == 'SeisComp': index = 0 @@ -2766,7 +2777,7 @@ class LocalisationTab(PropTab): return values def resetValues(self, infile): - para = AutoPickParameter(infile) + para = PylotParameter(infile) nllocroot = para.get('nllocroot') nllocbin = para.get('nllocbin') loctool = self.locToolComboBox.setCurrentIndex(3)