Merge branch 'develop' of ariadne.geophysik.ruhr-uni-bochum.de:/data/git/pylot into develop

This commit is contained in:
Marcel Paffrath 2017-12-06 14:53:18 +01:00
commit 1296e914c3
18 changed files with 504 additions and 161 deletions

View File

@ -338,6 +338,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
local_mag = LocalMagnitude(corr_dat, evt, local_mag = LocalMagnitude(corr_dat, evt,
parameter.get('sstop'), parameter.get('sstop'),
WAscaling, True, iplot) WAscaling, True, iplot)
# update pick with local magnitude property values
for stats, amplitude in local_mag.amplitudes.items(): for stats, amplitude in local_mag.amplitudes.items():
picks[stats]['S']['Ao'] = amplitude.generic_amplitude picks[stats]['S']['Ao'] = amplitude.generic_amplitude
print("Local station magnitudes scaled with:") print("Local station magnitudes scaled with:")
@ -412,6 +413,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
local_mag = LocalMagnitude(corr_dat, evt, local_mag = LocalMagnitude(corr_dat, evt,
parameter.get('sstop'), parameter.get('sstop'),
WAscaling, True, iplot) WAscaling, True, iplot)
# update pick with local magnitude property values
for stats, amplitude in local_mag.amplitudes.items(): for stats, amplitude in local_mag.amplitudes.items():
if stats in picks: if stats in picks:
picks[stats]['S']['Ao'] = amplitude.generic_amplitude picks[stats]['S']['Ao'] = amplitude.generic_amplitude

View File

@ -16,7 +16,6 @@ from pylot.core.util.utils import common_range, fit_curve
from scipy import integrate, signal from scipy import integrate, signal
from scipy.optimize import curve_fit from scipy.optimize import curve_fit
def richter_magnitude_scaling(delta): def richter_magnitude_scaling(delta):
distance = np.array([0, 10, 20, 25, 30, 35, 40, 45, 50, 60, 70, 75, 85, 90, 100, 110, distance = np.array([0, 10, 20, 25, 30, 35, 40, 45, 50, 60, 70, 75, 85, 90, 100, 110,
120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 230, 240, 250, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 230, 240, 250,
@ -133,7 +132,7 @@ class Magnitude(object):
station_count=len(self.magnitudes), station_count=len(self.magnitudes),
azimuthal_gap=self.origin_id.get_referred_object().quality.azimuthal_gap) azimuthal_gap=self.origin_id.get_referred_object().quality.azimuthal_gap)
else: else:
# no saling necessary # no scaling necessary
mag = ope.Magnitude( mag = ope.Magnitude(
mag=np.median([M.mag for M in self.magnitudes.values()]), mag=np.median([M.mag for M in self.magnitudes.values()]),
magnitude_type=self.type, magnitude_type=self.type,
@ -233,17 +232,33 @@ class LocalMagnitude(Magnitude):
# check for plot flag (for debugging only) # check for plot flag (for debugging only)
fig = None fig = None
if iplot > 1: if iplot > 1:
st.plot()
fig = plt.figure() fig = plt.figure()
ax = fig.add_subplot(111) ax = fig.add_subplot(211)
ax.plot(th, st[0].data, 'k')
ax.plot(th, sqH) ax.plot(th, sqH)
ax.plot(th[iwin], sqH[iwin], 'g') ax.plot(th[iwin], sqH[iwin], 'g')
ax.plot([t0, t0], [0, max(sqH)], 'r', linewidth=2) ax.plot([t0 - stime, t0 - stime], [0, max(sqH)], 'r', linewidth=2)
ax.title( ax.set_title('Station %s, Channel %s, RMS Horizontal Trace, '
'Station %s, RMS Horizontal Traces, WA-peak-to-peak=%4.1f mm' \ 'WA-peak-to-peak=%6.3f mm' % (st[0].stats.station,
% (st[0].stats.station, wapp)) st[0].stats.channel,
wapp))
ax.set_xlabel('Time [s]') ax.set_xlabel('Time [s]')
ax.set_ylabel('Displacement [mm]') ax.set_ylabel('Displacement [mm]')
ax = fig.add_subplot(212)
ax.plot(th, st[1].data, 'k')
ax.plot(th, sqH)
ax.plot(th[iwin], sqH[iwin], 'g')
ax.plot([t0 - stime, t0 - stime], [0, max(sqH)], 'r', linewidth=2)
ax.set_title('Channel %s, RMS Horizontal Trace, '
'WA-peak-to-peak=%6.3f mm' % (st[1].stats.channel,
wapp))
ax.set_xlabel('Time [s]')
ax.set_ylabel('Displacement [mm]')
fig.show()
try: input()
except SyntaxError: pass
plt.close(fig)
return wapp, fig return wapp, fig
@ -251,6 +266,10 @@ class LocalMagnitude(Magnitude):
for a in self.arrivals: for a in self.arrivals:
if a.phase not in 'sS': if a.phase not in 'sS':
continue continue
# make sure calculating Ml only from reliable onsets
# NLLoc: time_weight = 0 => do not use onset!
if a.time_weight == 0:
continue
pick = a.pick_id.get_referred_object() pick = a.pick_id.get_referred_object()
station = pick.waveform_id.station_code station = pick.waveform_id.station_code
wf = select_for_phase(self.stream.select( wf = select_for_phase(self.stream.select(
@ -347,7 +366,11 @@ class MomentMagnitude(Magnitude):
def calc(self): def calc(self):
for a in self.arrivals: for a in self.arrivals:
if a.phase not in 'pP': if a.phase not in 'pP':
continue
# make sure calculating Mo only from reliable onsets
# NLLoc: time_weight = 0 => do not use onset!
if a.time_weight == 0:
continue continue
pick = a.pick_id.get_referred_object() pick = a.pick_id.get_referred_object()
station = pick.waveform_id.station_code station = pick.waveform_id.station_code

View File

@ -99,6 +99,11 @@ class Data(object):
return self return self
def getPicksStr(self): def getPicksStr(self):
"""
Return picks in event data
:return: picks seperated by newlines
:rtype: str
"""
picks_str = '' picks_str = ''
for pick in self.get_evt_data().picks: for pick in self.get_evt_data().picks:
picks_str += str(pick) + '\n' picks_str += str(pick) + '\n'
@ -106,18 +111,11 @@ class Data(object):
def getParent(self): def getParent(self):
""" """
Get PySide.QtGui.QWidget parent object
:return:
""" """
return self._parent return self._parent
def isNew(self): def isNew(self):
"""
:return:
"""
return self._new return self._new
def setNew(self): def setNew(self):
@ -125,9 +123,9 @@ class Data(object):
def getCutTimes(self): def getCutTimes(self):
""" """
Returns earliest start and latest end of all waveform data
:return: minimum start time and maximum end time as a tuple
:return: :rtype: (UTCDateTime, UTCDateTime)
""" """
if self.cuttimes is None: if self.cuttimes is None:
self.updateCutTimes() self.updateCutTimes()
@ -135,22 +133,34 @@ class Data(object):
def updateCutTimes(self): def updateCutTimes(self):
""" """
Update cuttimes to contain earliest start and latest end time
of all waveform data
:rtype: None
""" """
self.cuttimes = full_range(self.getWFData()) self.cuttimes = full_range(self.getWFData())
def getEventFileName(self): def getEventFileName(self):
"""
:return:
"""
ID = self.getID() ID = self.getID()
# handle forbidden filenames especially on windows systems # handle forbidden filenames especially on windows systems
return fnConstructor(str(ID)) return fnConstructor(str(ID))
def checkEvent(self, event, fcheck, forceOverwrite=False): def checkEvent(self, event, fcheck, forceOverwrite=False):
"""
Check information in supplied event and own event and replace own
information with supplied information if own information not exiisting
or forced by forceOverwrite
:param event: Event that supplies information for comparison
:type event: pylot.core.util.event.Event
:param fcheck: check and delete existing information
can be a str or a list of strings of ['manual', 'auto', 'origin', 'magnitude']
:type fcheck: str, [str]
:param forceOverwrite: Set to true to force overwrite own information. If false,
supplied information from event is only used if there is no own information in that
category (given in fcheck: manual, auto, origin, magnitude)
:type forceOverwrite: bool
:return:
:rtype: None
"""
if 'origin' in fcheck: if 'origin' in fcheck:
self.replaceOrigin(event, forceOverwrite) self.replaceOrigin(event, forceOverwrite)
if 'magnitude' in fcheck: if 'magnitude' in fcheck:
@ -161,18 +171,47 @@ class Data(object):
self.replacePicks(event, 'manual') self.replacePicks(event, 'manual')
def replaceOrigin(self, event, forceOverwrite=False): def replaceOrigin(self, event, forceOverwrite=False):
"""
Replace own origin with the one supplied in event if own origin is not
existing or forced by forceOverwrite = True
:param event: Event that supplies information for comparison
:type event: pylot.core.util.event.Event
:param forceOverwrite: always replace own information with supplied one if true
:type forceOverwrite: bool
:return:
:rtype: None
"""
if self.get_evt_data().origins or forceOverwrite: if self.get_evt_data().origins or forceOverwrite:
if event.origins: if event.origins:
print("Found origin, replace it by new origin.") print("Found origin, replace it by new origin.")
event.origins = self.get_evt_data().origins event.origins = self.get_evt_data().origins
def replaceMagnitude(self, event, forceOverwrite=False): def replaceMagnitude(self, event, forceOverwrite=False):
"""
Replace own magnitude with the one supplied in event if own magnitude is not
existing or forced by forceOverwrite = True
:param event: Event that supplies information for comparison
:type event: pylot.core.util.event.Event
:param forceOverwrite: always replace own information with supplied one if true
:type forceOverwrite: bool
:return:
:rtype: None
"""
if self.get_evt_data().magnitudes or forceOverwrite: if self.get_evt_data().magnitudes or forceOverwrite:
if event.magnitudes: if event.magnitudes:
print("Found magnitude, replace it by new magnitude") print("Found magnitude, replace it by new magnitude")
event.magnitudes = self.get_evt_data().magnitudes event.magnitudes = self.get_evt_data().magnitudes
def replacePicks(self, event, picktype): def replacePicks(self, event, picktype):
"""
Replace own picks with the one in event
:param event: Event that supplies information for comparison
:type event: pylot.core.util.event.Event
:param picktype: 'auto' or 'manual' picks
:type picktype: str
:return:
:rtype: None
"""
checkflag = 0 checkflag = 0
picks = event.picks picks = event.picks
# remove existing picks # remove existing picks
@ -189,10 +228,10 @@ class Data(object):
picks.append(pick) picks.append(pick)
def exportEvent(self, fnout, fnext='.xml', fcheck='auto', upperErrors=None): def exportEvent(self, fnout, fnext='.xml', fcheck='auto', upperErrors=None):
""" """
Export event to file
:param fnout: basename of file :param fnout: basename of file
:param fnext: file extension :param fnext: file extension, xml, cnv, obs
:param fcheck: check and delete existing information :param fcheck: check and delete existing information
can be a str or a list of strings of ['manual', 'auto', 'origin', 'magnitude'] can be a str or a list of strings of ['manual', 'auto', 'origin', 'magnitude']
""" """
@ -304,17 +343,13 @@ class Data(object):
def getComp(self): def getComp(self):
""" """
Get component (ZNE)
:return:
""" """
return self.comp return self.comp
def getID(self): def getID(self):
""" """
Get unique resource id
:return:
""" """
try: try:
return self.evtdata.get('resource_id').id return self.evtdata.get('resource_id').id
@ -323,16 +358,17 @@ class Data(object):
def filterWFData(self, kwargs): def filterWFData(self, kwargs):
""" """
Filter waveform data
:param kwargs: :param kwargs: arguments to pass through to filter function
""" """
self.getWFData().filter(**kwargs) self.getWFData().filter(**kwargs)
self.dirty = True self.dirty = True
def setWFData(self, fnames): def setWFData(self, fnames):
""" """
Clear current waveform data and set given waveform data
:param fnames: :param fnames: waveform data names to append
:type fnames: list
""" """
self.wfdata = Stream() self.wfdata = Stream()
self.wforiginal = None self.wforiginal = None
@ -346,8 +382,9 @@ class Data(object):
def appendWFData(self, fnames): def appendWFData(self, fnames):
""" """
Read waveform data from fnames and append it to current wf data
:param fnames: :param fnames: waveform data to append
:type fnames: list
""" """
assert isinstance(fnames, list), "input parameter 'fnames' is " \ assert isinstance(fnames, list), "input parameter 'fnames' is " \
"supposed to be of type 'list' " \ "supposed to be of type 'list' " \
@ -372,54 +409,42 @@ class Data(object):
print(warnmsg) print(warnmsg)
def getWFData(self): def getWFData(self):
"""
:return:
"""
return self.wfdata return self.wfdata
def getOriginalWFData(self): def getOriginalWFData(self):
"""
:return:
"""
return self.wforiginal return self.wforiginal
def resetWFData(self): def resetWFData(self):
""" """
Set waveform data to original waveform data
""" """
self.wfdata = self.getOriginalWFData().copy() self.wfdata = self.getOriginalWFData().copy()
self.dirty = False self.dirty = False
def resetPicks(self): def resetPicks(self):
""" """
Clear all picks from event
""" """
self.get_evt_data().picks = [] self.get_evt_data().picks = []
def get_evt_data(self): def get_evt_data(self):
"""
:return:
"""
return self.evtdata return self.evtdata
def setEvtData(self, event): def setEvtData(self, event):
self.evtdata = event self.evtdata = event
def applyEVTData(self, data, typ='pick', authority_id='rub'): def applyEVTData(self, data, typ='pick', authority_id='rub'):
""" """
Either takes an `obspy.core.event.Event` object and applies all new
:param data: information on the event to the actual data if typ is 'event or
:param typ: creates ObsPy pick objects and append it to the picks list from the
:param authority_id: PyLoT dictionary contain all picks if type is pick
:param data: data to apply, either picks or complete event
:type data:
:param typ: which event data to apply, 'pick' or 'event'
:type typ: str
:param authority_id: (currently unused)
:type: str
:raise OverwriteError: :raise OverwriteError:
""" """

View File

@ -1,6 +1,10 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""
Default parameters used for picking
"""
defaults = {'rootpath': {'type': str, defaults = {'rootpath': {'type': str,
'tooltip': 'project path', 'tooltip': 'project path',
'value': '', 'value': '',

View File

@ -70,6 +70,7 @@ class PylotParameter(object):
# Set default values of parameter names # Set default values of parameter names
def __init_default_paras(self): def __init_default_paras(self):
"""set default values of parameter names"""
parameters = default_parameters.defaults parameters = default_parameters.defaults
self.__defaults = parameters self.__defaults = parameters
@ -104,15 +105,34 @@ class PylotParameter(object):
return len(self.__parameter.keys()) return len(self.__parameter.keys())
def iteritems(self): def iteritems(self):
"""
Iterate over parameters
:return: key, value tupel
:rtype:
"""
for key, value in self.__parameter.items(): for key, value in self.__parameter.items():
yield key, value yield key, value
def hasParam(self, parameter): def hasParam(self, parameter):
"""
Check if parameter is in keys
:param parameter: parameter to look for in keys
:type parameter:
:return:
:rtype: bool
"""
if parameter in self.__parameter.keys(): if parameter in self.__parameter.keys():
return True return True
return False return False
def get(self, *args): def get(self, *args):
"""
Get first available parameter in args
:param args:
:type args:
:return:
:rtype:
"""
try: try:
for param in args: for param in args:
try: try:
@ -128,15 +148,35 @@ class PylotParameter(object):
raise ParameterError(e) raise ParameterError(e)
def get_defaults(self): def get_defaults(self):
"""
get default parameters
:return:
:rtype: dict
"""
return self.__defaults return self.__defaults
def get_main_para_names(self): def get_main_para_names(self):
"""
Get main parameter names
:return: list of keys available in parameters
:rtype:
"""
return self._settings_main return self._settings_main
def get_special_para_names(self): def get_special_para_names(self):
"""
Get pick parameter names
:return: list of keys available in parameters
:rtype:
"""
return self._settings_special_pick return self._settings_special_pick
def get_all_para_names(self): def get_all_para_names(self):
"""
Get all parameter names
:return:
:rtype: list
"""
all_names = [] all_names = []
all_names += self.get_main_para_names()['dirs'] all_names += self.get_main_para_names()['dirs']
all_names += self.get_main_para_names()['nlloc'] all_names += self.get_main_para_names()['nlloc']
@ -151,6 +191,16 @@ class PylotParameter(object):
return all_names return all_names
def checkValue(self, param, value): def checkValue(self, param, value):
"""
Check type of value against expected type of param.
Print warning message if type check fails
:param param:
:type param:
:param value:
:type value:
:return:
:rtype:
"""
is_type = type(value) is_type = type(value)
expect_type = self.get_defaults()[param]['type'] expect_type = self.get_defaults()[param]['type']
if not is_type == expect_type and not is_type == tuple: if not is_type == expect_type and not is_type == tuple:
@ -159,9 +209,25 @@ class PylotParameter(object):
print(Warning(message)) print(Warning(message))
def setParamKV(self, param, value): def setParamKV(self, param, value):
"""
set parameter param to value
:param param:
:type param:
:param value:
:type value:
:return:
:rtype: None
"""
self.__setitem__(param, value) self.__setitem__(param, value)
def setParam(self, **kwargs): def setParam(self, **kwargs):
"""
Set multiple parameters
:param kwargs:
:type kwargs:
:return:
:rtype: None
"""
for key in kwargs: for key in kwargs:
self.__setitem__(key, kwargs[key]) self.__setitem__(key, kwargs[key])
@ -170,11 +236,23 @@ class PylotParameter(object):
print('ParameterError:\n non-existent parameter %s' % errmsg) print('ParameterError:\n non-existent parameter %s' % errmsg)
def reset_defaults(self): def reset_defaults(self):
"""
Reset current parameters to default parameters
:return:
:rtype: None
"""
defaults = self.get_defaults() defaults = self.get_defaults()
for param in defaults: for param in defaults:
self.setParamKV(param, defaults[param]['value']) self.setParamKV(param, defaults[param]['value'])
def from_file(self, fnin=None): def from_file(self, fnin=None):
"""
read parameters from file and set values to read values
:param fnin: filename
:type fnin:
:return:
:rtype: None
"""
if not fnin: if not fnin:
if self.__filename is not None: if self.__filename is not None:
fnin = self.__filename fnin = self.__filename
@ -221,6 +299,13 @@ class PylotParameter(object):
self.__parameter = self._parFileCont self.__parameter = self._parFileCont
def export2File(self, fnout): def export2File(self, fnout):
"""
Export parameters to file
:param fnout: Filename of export file
:type fnout: str
:return:
:rtype:
"""
fid_out = open(fnout, 'w') fid_out = open(fnout, 'w')
lines = [] lines = []
# for key, value in self.iteritems(): # for key, value in self.iteritems():
@ -257,6 +342,19 @@ class PylotParameter(object):
'quality assessment', None) 'quality assessment', None)
def write_section(self, fid, names, title, separator): def write_section(self, fid, names, title, separator):
"""
write a section of parameters to file
:param fid: File object to write to
:type fid:
:param names: which parameter names to write to file
:type names:
:param title: title of section
:type title: str
:param separator: section separator, written at start of section
:type separator: str
:return:
:rtype:
"""
if separator: if separator:
fid.write(separator) fid.write(separator)
fid.write('#{}#\n'.format(title)) fid.write('#{}#\n'.format(title))

View File

@ -54,7 +54,7 @@ def create_arrival(pickresID, cinfo, phase, azimuth=None, dist=None):
def create_creation_info(agency_id=None, creation_time=None, author=None): def create_creation_info(agency_id=None, creation_time=None, author=None):
''' '''
get creation info of obspy event
:param agency_id: :param agency_id:
:param creation_time: :param creation_time:
:param author: :param author:
@ -197,9 +197,9 @@ def create_pick(origintime, picknum, picktime, eventnum, cinfo, phase, station,
def create_resourceID(timetohash, restype, authority_id=None, hrstr=None): def create_resourceID(timetohash, restype, authority_id=None, hrstr=None):
''' '''
create unique resource id
:param timetohash: :param timetohash: event origin time to hash
:type timetohash :type timetohash: class: `~obspy.core.utcdatetime.UTCDateTime` object
:param restype: type of the resource, e.g. 'orig', 'earthquake' ... :param restype: type of the resource, e.g. 'orig', 'earthquake' ...
:type restype: str :type restype: str
:param authority_id: name of the institution carrying out the processing :param authority_id: name of the institution carrying out the processing

View File

@ -118,6 +118,13 @@ def readPILOTEvent(phasfn=None, locfn=None, authority_id='RUB', **kwargs):
def picksdict_from_pilot(fn): def picksdict_from_pilot(fn):
"""
Create pick dictionary from matlab file
:param fn: matlab file
:type fn:
:return: pick dictionary
:rtype: dict
"""
from pylot.core.util.defaults import TIMEERROR_DEFAULTS from pylot.core.util.defaults import TIMEERROR_DEFAULTS
picks = dict() picks = dict()
phases_pilot = sio.loadmat(fn) phases_pilot = sio.loadmat(fn)
@ -147,6 +154,13 @@ def picksdict_from_pilot(fn):
def stations_from_pilot(stat_array): def stations_from_pilot(stat_array):
"""
Create stations list from pilot station array
:param stat_array:
:type stat_array:
:return:
:rtype: list
"""
stations = list() stations = list()
cur_stat = None cur_stat = None
for stat in stat_array: for stat in stat_array:
@ -164,6 +178,13 @@ def stations_from_pilot(stat_array):
def convert_pilot_times(time_array): def convert_pilot_times(time_array):
"""
Convert pilot times to UTCDateTimes
:param time_array: pilot times
:type time_array:
:return:
:rtype:
"""
times = [int(time) for time in time_array] times = [int(time) for time in time_array]
microseconds = int((time_array[-1] - times[-1]) * 1e6) microseconds = int((time_array[-1] - times[-1]) * 1e6)
times.append(microseconds) times.append(microseconds)
@ -171,6 +192,13 @@ def convert_pilot_times(time_array):
def picksdict_from_obs(fn): def picksdict_from_obs(fn):
"""
create pick dictionary from obs file
:param fn: filename
:type fn:
:return:
:rtype:
"""
picks = dict() picks = dict()
station_name = str() station_name = str()
for line in open(fn, 'r'): for line in open(fn, 'r'):
@ -240,6 +268,16 @@ def picksdict_from_picks(evt):
def picks_from_picksdict(picks, creation_info=None): def picks_from_picksdict(picks, creation_info=None):
"""
Create a list of picks out of a pick dictionary
:param picks: pick dictionary
:type picks: dict
:param creation_info: obspy creation information to apply to picks
:type creation_info:
:param creation_info: obspy creation information to apply to picks
:return: list of picks
:rtype: list
"""
picks_list = list() picks_list = list()
for station, onsets in picks.items(): for station, onsets in picks.items():
for label, phase in onsets.items(): for label, phase in onsets.items():
@ -410,25 +448,24 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
HYPO71, NLLoc, VELEST, HYPOSAT, and hypoDD HYPO71, NLLoc, VELEST, HYPOSAT, and hypoDD
:param: arrivals :param arrivals:dictionary containing all phase information including
:type: dictionary containing all phase information including station ID, phase, first motion, weight (uncertainty), ...
station ID, phase, first motion, weight (uncertainty), :type arrivals: dict
....
:param: fformat :param fformat: chosen file format (location routine),
:type: string, chosen file format (location routine), choose between NLLoc, HYPO71, HYPOSAT, VELEST,
choose between NLLoc, HYPO71, HYPOSAT, VELEST, HYPOINVERSE, and hypoDD
HYPOINVERSE, and hypoDD :type fformat: str
:param: filename, full path and name of phase file :param filename: full path and name of phase file
:type: string :type filename: string
:param: parameter, all input information :param parameter: all input information
:type: object :type parameter: object
:param: eventinfo, optional, needed for VELEST-cnv file :param eventinfo: optional, needed for VELEST-cnv file
and FOCMEC- and HASH-input files and FOCMEC- and HASH-input files
:type: `obspy.core.event.Event` object :type eventinfo: `obspy.core.event.Event` object
""" """
if fformat == 'NLLoc': if fformat == 'NLLoc':
@ -874,10 +911,20 @@ def merge_picks(event, picks):
def getQualitiesfromxml(xmlnames, ErrorsP, ErrorsS, plotflag=1): def getQualitiesfromxml(xmlnames, ErrorsP, ErrorsS, plotflag=1):
""" """
Script to get onset uncertainties from Quakeml.xml files created by PyLoT. Script to get onset uncertainties from Quakeml.xml files created by PyLoT.
Uncertainties are tranformed into quality classes and visualized via histogram if desired. Uncertainties are tranformed into quality classes and visualized via histogram if desired.
Ludger Küperkoch, BESTEC GmbH, 07/2017 Ludger Küperkoch, BESTEC GmbH, 07/2017
""" :param xmlnames: list of xml obspy event files containing picks
:type xmlnames: list
:param ErrorsP: time errors of P waves for the four discrete quality classes
:type ErrorsP:
:param ErrorsS: time errors of S waves for the four discrete quality classes
:type ErrorsS:
:param plotflag:
:type plotflag:
:return:
:rtype:
"""
from pylot.core.pick.utils import getQualityFromUncertainty from pylot.core.pick.utils import getQualityFromUncertainty
from pylot.core.util.utils import loopIdentifyPhase, identifyPhase from pylot.core.util.utils import loopIdentifyPhase, identifyPhase

View File

@ -18,11 +18,11 @@ def export(picks, fnout, parameter, eventinfo):
:param fnout: complete path to the exporting obs file :param fnout: complete path to the exporting obs file
:type fnout: str :type fnout: str
:param: parameter, all input information :param parameter: all input information
:type: object :type parameter: object
:param: eventinfo, source information needed for focmec format :param eventinfo: source information needed for focmec format
:type: list object :type eventinfo: list object
''' '''
# write phases to FOCMEC-phase file # write phases to FOCMEC-phase file
writephases(picks, 'FOCMEC', fnout, parameter, eventinfo) writephases(picks, 'FOCMEC', fnout, parameter, eventinfo)

View File

@ -18,11 +18,11 @@ def export(picks, fnout, parameter, eventinfo):
:param fnout: complete path to the exporting obs file :param fnout: complete path to the exporting obs file
:type fnout: str :type fnout: str
:param: parameter, all input information :param parameter: all input information
:type: object :type parameter: object
:param: eventinfo, source information needed for HASH format :param eventinfo: source information needed for HASH format
:type: list object :type eventinfo: list object
''' '''
# write phases to HASH-phase file # write phases to HASH-phase file
writephases(picks, 'HASH', fnout, parameter, eventinfo) writephases(picks, 'HASH', fnout, parameter, eventinfo)

View File

@ -18,8 +18,8 @@ def export(picks, fnout, parameter):
:param fnout: complete path to the exporting obs file :param fnout: complete path to the exporting obs file
:type fnout: str :type fnout: str
:param: parameter, all input information :param parameter: all input information
:type: object :type parameter: object
''' '''
# write phases to HYPO71-phase file # write phases to HYPO71-phase file
writephases(picks, 'HYPO71', fnout, parameter) writephases(picks, 'HYPO71', fnout, parameter)

View File

@ -18,11 +18,11 @@ def export(picks, fnout, parameter, eventinfo):
:param fnout: complete path to the exporting obs file :param fnout: complete path to the exporting obs file
:type fnout: str :type fnout: str
:param: parameter, all input information :param parameter: all input information
:type: object :type parameter: object
:param: eventinfo, source information needed for hypoDD format :param eventinfo: source information needed for hypoDD format
:type: list object :type eventinfo: list object
''' '''
# write phases to hypoDD-phase file # write phases to hypoDD-phase file
writephases(picks, 'hypoDD', fnout, parameter, eventinfo) writephases(picks, 'hypoDD', fnout, parameter, eventinfo)

View File

@ -18,8 +18,8 @@ def export(picks, fnout, parameter):
:param fnout: complete path to the exporting obs file :param fnout: complete path to the exporting obs file
:type fnout: str :type fnout: str
:param: parameter, all input information :param parameter: all input information
:type: object :type parameter: object
''' '''
# write phases to HYPOSAT-phase file # write phases to HYPOSAT-phase file
writephases(picks, 'HYPOSAT', fnout, parameter) writephases(picks, 'HYPOSAT', fnout, parameter)

View File

@ -28,8 +28,8 @@ def export(picks, fnout, parameter):
:param fnout: complete path to the exporting obs file :param fnout: complete path to the exporting obs file
:type fnout: str :type fnout: str
:param: parameter, all input information :param parameter: all input information
:type: object :type parameter: object
''' '''
# write phases to NLLoc-phase file # write phases to NLLoc-phase file
writephases(picks, 'NLLoc', fnout, parameter) writephases(picks, 'NLLoc', fnout, parameter)
@ -38,19 +38,19 @@ def export(picks, fnout, parameter):
def modify_inputs(ctrfn, root, nllocoutn, phasefn, tttn): def modify_inputs(ctrfn, root, nllocoutn, phasefn, tttn):
''' '''
:param ctrfn: name of NLLoc-control file :param ctrfn: name of NLLoc-control file
:type: str :type ctrfn: str
:param root: root path to NLLoc working directory :param root: root path to NLLoc working directory
:type: str :type root: str
:param nllocoutn: name of NLLoc-location output file :param nllocoutn: name of NLLoc-location output file
:type: str :type nllocoutn: str
:param phasefn: name of NLLoc-input phase file :param phasefn: name of NLLoc-input phase file
:type: str :type phasefn: str
:param tttn: pattern of precalculated NLLoc traveltime tables :param tttn: pattern of precalculated NLLoc traveltime tables
:type: str :type tttn: str
''' '''
# For locating the event the NLLoc-control file has to be modified! # For locating the event the NLLoc-control file has to be modified!
# create comment line for NLLoc-control file NLLoc-output file # create comment line for NLLoc-control file NLLoc-output file
@ -75,9 +75,9 @@ def modify_inputs(ctrfn, root, nllocoutn, phasefn, tttn):
def locate(fnin, infile=None): def locate(fnin, infile=None):
""" """
takes an external program name takes an external program name and tries to run it
:param fnin: :param fnin: external program name
:return: :return: None
""" """
if infile is None: if infile is None:

View File

@ -18,11 +18,11 @@ def export(picks, fnout, eventinfo, parameter=None):
:param fnout: complete path to the exporting obs file :param fnout: complete path to the exporting obs file
:type fnout: str :type fnout: str
:param: eventinfo, source time needed for VELEST-cnv format :param eventinfo: source time needed for VELEST-cnv format
:type: list object :type eventinfo: list object
:param: parameter, all input information :param parameter: all input information
:type: object :type parameter: object
''' '''
# write phases to VELEST-phase file # write phases to VELEST-phase file
writephases(picks, 'VELEST', fnout, parameter, eventinfo) writephases(picks, 'VELEST', fnout, parameter, eventinfo)

View File

@ -155,7 +155,7 @@ def autopickstation(wfstream, pickparam, verbose=False,
:type metadata: tuple (str, ~obspy.io.xseed.parser.Parser) :type metadata: tuple (str, ~obspy.io.xseed.parser.Parser)
:param origin: list containing origin objects representing origins for all events :param origin: list containing origin objects representing origins for all events
:type origin: list(~obspy.core.event.origin) :type origin: list(~obspy.core.event.origin)
:return: :dictionary containing P pick, S pick and station name :return: dictionary containing P pick, S pick and station name
:rtype: dict :rtype: dict
""" """

View File

@ -29,38 +29,36 @@ from pylot.core.pick.utils import getnoisewin, getsignalwin
class AutoPicker(object): class AutoPicker(object):
''' """
Superclass of different, automated picking algorithms applied on a CF determined Superclass of different, automated picking algorithms applied on a CF determined
using AIC, HOS, or AR prediction. using AIC, HOS, or AR prediction.
''' """
warnings.simplefilter('ignore') warnings.simplefilter('ignore')
def __init__(self, cf, TSNR, PickWindow, iplot=0, aus=None, Tsmooth=None, Pick1=None, fig=None, linecolor='k'): def __init__(self, cf, TSNR, PickWindow, iplot=0, aus=None, Tsmooth=None, Pick1=None, fig=None, linecolor='k'):
''' """
:param: cf, characteristic function, on which the picking algorithm is applied Create AutoPicker object
:type: `~pylot.core.pick.CharFuns.CharacteristicFunction` object :param cf: characteristic function, on which the picking algorithm is applied
:type cf: `~pylot.core.pick.CharFuns.CharacteristicFunction`
:param: TSNR, length of time windows around pick used to determine SNR [s] :param TSNR: length of time windows around pick used to determine SNR [s], tuple (T_noise, T_gap, T_signal)
:type: tuple (T_noise, T_gap, T_signal) :type TSNR: (float, float, float)
:param PickWindow: length of pick window [s]
:param: PickWindow, length of pick window [s] :type PickWindow: float
:type: float :param iplot: flag used for plotting, if > 1, results will be plotted. Use iplot = 0 to disable plotting
:type iplot: int
:param: iplot, no. of figure window for plotting interims results :param aus: ("artificial uplift of samples"), find local minimum at i if aic(i-1)*(1+aus) >= aic(i)
:type: integer :type aus: float
:param Tsmooth: length of moving smoothing window to calculate smoothed CF [s]
:param: aus ("artificial uplift of samples"), find local minimum at i if aic(i-1)*(1+aus) >= aic(i) :type Tsmooth: float
:type: float :param Pick1: initial (preliminary) onset time, starting point for PragPicker and EarlLatePicker
:type Pick1: float
:param: Tsmooth, length of moving smoothing window to calculate smoothed CF [s] :param fig: matplotlib figure used for plotting. If not given and plotting is enabled, a new figure will
:type: float be created
:type fig: `~matplotlib.figure.Figure`
:param: Pick1, initial (prelimenary) onset time, starting point for PragPicker and :param linecolor: matplotlib line color string
EarlLatePicker :type linecolor: str
:type: float """
'''
assert isinstance(cf, CharacteristicFunction), "%s is not a CharacteristicFunction object" % str(cf) assert isinstance(cf, CharacteristicFunction), "%s is not a CharacteristicFunction object" % str(cf)
self._linecolor = linecolor self._linecolor = linecolor
@ -79,6 +77,11 @@ class AutoPicker(object):
self.calcPick() self.calcPick()
def __str__(self): def __str__(self):
"""
String representation of AutoPicker object
:return:
:rtype: str
"""
return '''\n\t{name} object:\n return '''\n\t{name} object:\n
TSNR:\t\t\t{TSNR}\n TSNR:\t\t\t{TSNR}\n
PickWindow:\t{PickWindow}\n PickWindow:\t{PickWindow}\n
@ -142,12 +145,12 @@ class AutoPicker(object):
class AICPicker(AutoPicker): class AICPicker(AutoPicker):
''' """
Method to derive the onset time of an arriving phase based on CF Method to derive the onset time of an arriving phase based on CF
derived from AIC. In order to get an impression of the quality of this inital pick, derived from AIC. In order to get an impression of the quality of this initial pick,
a quality assessment is applied based on SNR and slope determination derived from the CF, a quality assessment is applied based on SNR and slope determination derived from the CF,
from which the AIC has been calculated. from which the AIC has been calculated.
''' """
def calcPick(self): def calcPick(self):
@ -214,6 +217,12 @@ class AICPicker(AutoPicker):
self.Pick = self.Tcf[i] self.Pick = self.Tcf[i]
break break
def calcPick(self):
"""
Calculate pick using cf derived from AIC
:return:
:rtype: None
"""
# quality assessment using SNR and slope from CF # quality assessment using SNR and slope from CF
if self.Pick is not None: if self.Pick is not None:
# get noise window # get noise window
@ -364,9 +373,9 @@ class AICPicker(AutoPicker):
class PragPicker(AutoPicker): class PragPicker(AutoPicker):
''' """
Method of pragmatic picking exploiting information given by CF. Method of pragmatic picking exploiting information given by CF.
''' """
def calcPick(self): def calcPick(self):

View File

@ -8,6 +8,13 @@ except:
def checkurl(url='https://ariadne.geophysik.ruhr-uni-bochum.de/trac/PyLoT/'): def checkurl(url='https://ariadne.geophysik.ruhr-uni-bochum.de/trac/PyLoT/'):
"""
check if URL is available
:param url: url
:type url: str
:return: available: True/False
:rtype: bool
"""
try: try:
urlopen(url, timeout=1) urlopen(url, timeout=1)
return True return True

View File

@ -15,6 +15,11 @@ class Event(ObsPyEvent):
''' '''
def __init__(self, path): def __init__(self, path):
"""
Initialize event by event directory
:param path: path to event directory
:type path: str
"""
self.pylot_id = path.split('/')[-1] self.pylot_id = path.split('/')[-1]
# initialize super class # initialize super class
super(Event, self).__init__(resource_id=ResourceIdentifier('smi:local/' + self.pylot_id)) super(Event, self).__init__(resource_id=ResourceIdentifier('smi:local/' + self.pylot_id))
@ -30,10 +35,20 @@ class Event(ObsPyEvent):
self.get_notes() self.get_notes()
def get_notes_path(self): def get_notes_path(self):
"""
Notes files is freely editable by the user and can contain notes regarding the event
:return: path to notes file
:rtype: str
"""
notesfile = os.path.join(self.path, 'notes.txt') notesfile = os.path.join(self.path, 'notes.txt')
return notesfile return notesfile
def get_notes(self): def get_notes(self):
"""
set self.note attribute to content of notes file
:return:
:rtype: None
"""
notesfile = self.get_notes_path() notesfile = self.get_notes_path()
if os.path.isfile(notesfile): if os.path.isfile(notesfile):
with open(notesfile) as infile: with open(notesfile) as infile:
@ -48,34 +63,81 @@ class Event(ObsPyEvent):
pass pass
def addNotes(self, notes): def addNotes(self, notes):
"""
Set new notes string
:param notes: notes to save in Event object
:type notes: str
:return:
:rtype: None
"""
self.notes = str(notes) self.notes = str(notes)
def clearNotes(self): def clearNotes(self):
"""
Clear event notes
:return:
:rtype: None
"""
self.notes = None self.notes = None
def isRefEvent(self): def isRefEvent(self):
"""
Return reference event flag
:return: True if event is refence event
:rtype: bool
"""
return self._refEvent return self._refEvent
def isTestEvent(self): def isTestEvent(self):
"""
Return test event flag
:return: True if event is test event
:rtype: bool
"""
return self._testEvent return self._testEvent
def setRefEvent(self, bool): def setRefEvent(self, bool):
"""
Set reference event flag
:param bool: new reference event flag
:type bool: bool
:return:
:rtype: None
"""
self._refEvent = bool self._refEvent = bool
if bool: self._testEvent = False if bool: self._testEvent = False
def setTestEvent(self, bool): def setTestEvent(self, bool):
"""
Set test event flag
:param bool: new test event flag
:type bool: bool
:return:
:rtype: None
"""
self._testEvent = bool self._testEvent = bool
if bool: self._refEvent = False if bool: self._refEvent = False
def clearObsPyPicks(self, picktype): def clearObsPyPicks(self, picktype):
"""
Remove picks of a certain type from event
:param picktype: type of picks to remove, 'auto' or 'manual'
:type picktype: str
:return:
:rtype: None
"""
for index, pick in reversed(list(enumerate(self.picks))): for index, pick in reversed(list(enumerate(self.picks))):
if picktype in str(pick.method_id): if picktype in str(pick.method_id):
self.picks.pop(index) self.picks.pop(index)
def addPicks(self, picks): def addPicks(self, picks):
''' """
add pylot picks and overwrite existing ones add pylot picks and overwrite existing ones
''' :param picks: picks to add to event in pick dictionary
:type picks: dict
:return:
:rtype: None
"""
for station in picks: for station in picks:
self.pylot_picks[station] = picks[station] self.pylot_picks[station] = picks[station]
# add ObsPy picks (clear old manual and copy all new manual from pylot) # add ObsPy picks (clear old manual and copy all new manual from pylot)
@ -83,6 +145,13 @@ class Event(ObsPyEvent):
self.picks += picks_from_picksdict(self.pylot_picks) self.picks += picks_from_picksdict(self.pylot_picks)
def addAutopicks(self, autopicks): def addAutopicks(self, autopicks):
"""
Add automatic picks to event
:param autopicks: automatic picks to add to event
:type autopicks dict:
:return:
:rtype: None
"""
for station in autopicks: for station in autopicks:
self.pylot_autopicks[station] = autopicks[station] self.pylot_autopicks[station] = autopicks[station]
# add ObsPy picks (clear old auto and copy all new auto from pylot) # add ObsPy picks (clear old auto and copy all new auto from pylot)
@ -90,6 +159,15 @@ class Event(ObsPyEvent):
self.picks += picks_from_picksdict(self.pylot_autopicks) self.picks += picks_from_picksdict(self.pylot_autopicks)
def setPick(self, station, pick): def setPick(self, station, pick):
"""
Set pick for a station
:param station: station name
:type station: str
:param pick:
:type pick: dict
:return:
:rtype:
"""
if pick: if pick:
self.pylot_picks[station] = pick self.pylot_picks[station] = pick
else: else:
@ -101,21 +179,46 @@ class Event(ObsPyEvent):
self.picks += picks_from_picksdict(self.pylot_picks) self.picks += picks_from_picksdict(self.pylot_picks)
def setPicks(self, picks): def setPicks(self, picks):
''' """
set pylot picks and delete and overwrite all existing Set pylot picks and delete and overwrite all existing
''' :param picks: new picks
:type picks: dict
:return:
:rtype: None
"""
self.pylot_picks = picks self.pylot_picks = picks
self.clearObsPyPicks('manual') self.clearObsPyPicks('manual')
self.picks += picks_from_picksdict(self.pylot_picks) self.picks += picks_from_picksdict(self.pylot_picks)
def getPick(self, station): def getPick(self, station):
"""
Get pick at station
:param station: station name
:type station: str
:return: pick dictionary of station
:rtype: dict
"""
if station in self.pylot_picks.keys(): if station in self.pylot_picks.keys():
return self.pylot_picks[station] return self.pylot_picks[station]
def getPicks(self): def getPicks(self):
"""
Return pylot picks
:return:
:rtype: dict
"""
return self.pylot_picks return self.pylot_picks
def setAutopick(self, station, pick): def setAutopick(self, station, pick):
"""
Set pick at station
:param station: station name
:type station: str
:param pick:
:type pick: dict
:return:
:rtype: None
"""
if pick: if pick:
self.pylot_autopicks[station] = pick self.pylot_autopicks[station] = pick
else: else:
@ -127,25 +230,46 @@ class Event(ObsPyEvent):
self.picks += picks_from_picksdict(self.pylot_autopicks) self.picks += picks_from_picksdict(self.pylot_autopicks)
def setAutopicks(self, picks): def setAutopicks(self, picks):
''' """
set pylot picks and delete and overwrite all existing Set pylot picks and delete and overwrite all existing
''' :param picks: new picks
:type picks: dict
:return:
:rtype: None
"""
self.pylot_autopicks = picks self.pylot_autopicks = picks
self.clearObsPyPicks('auto') self.clearObsPyPicks('auto')
self.picks += picks_from_picksdict(self.pylot_autopicks) self.picks += picks_from_picksdict(self.pylot_autopicks)
def getAutopick(self, station): def getAutopick(self, station):
"""
Return autopick at station
:param station: station name
:type station: str
:return: pick dictionary
:rtype: dict
"""
if station in self.pylot_autopicks.keys(): if station in self.pylot_autopicks.keys():
return self.pylot_autopicks[station] return self.pylot_autopicks[station]
def getAutopicks(self): def getAutopicks(self):
"""
Get autopicks of event
:return: dict containing automatic picks
:rtype: dict
"""
return self.pylot_autopicks return self.pylot_autopicks
def save(self, filename): def save(self, filename):
''' """
Save PyLoT Event to a file. Save PyLoT Event to a file.
Can be loaded by using event.load(filename). Can be loaded by using event.load(filename).
''' Uses pickling to save event object to file
:param filename: filename to save project under
:type filename: str
:return:
:rtype: None
"""
try: try:
import cPickle import cPickle
except ImportError: except ImportError:
@ -159,9 +283,13 @@ class Event(ObsPyEvent):
@staticmethod @staticmethod
def load(filename): def load(filename):
''' """
Load project from filename. Load project from filename
''' :param filename: to load event file
:type filename: str
:return: event loaded from file
:rtype: Event
"""
try: try:
import cPickle import cPickle
except ImportError: except ImportError: