[change] docstrings in util/utils.py
This commit is contained in:
parent
7086d43076
commit
149fe3f74d
@ -33,11 +33,25 @@ def _pickle_method(m):
|
|||||||
|
|
||||||
|
|
||||||
def readDefaultFilterInformation(fname):
|
def readDefaultFilterInformation(fname):
|
||||||
|
"""
|
||||||
|
Read default filter information from pylot.in file
|
||||||
|
:param fname: path to pylot.in file
|
||||||
|
:type fname: str
|
||||||
|
:return: dictionary containing the defailt filter information
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
pparam = PylotParameter(fname)
|
pparam = PylotParameter(fname)
|
||||||
return readFilterInformation(pparam)
|
return readFilterInformation(pparam)
|
||||||
|
|
||||||
|
|
||||||
def readFilterInformation(pylot_parameter):
|
def readFilterInformation(pylot_parameter):
|
||||||
|
"""
|
||||||
|
Read filter information from PylotParameter object into a dictionary
|
||||||
|
:param pylot_parameter: PylotParameter object
|
||||||
|
:type pylot_parameter: `~pylot.pylot.core.io.inputs.PylotParameter`
|
||||||
|
:return: dictionary containing the filter information
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
p_filter = {'filtertype': pylot_parameter['filter_type'][0],
|
p_filter = {'filtertype': pylot_parameter['filter_type'][0],
|
||||||
'freq': [pylot_parameter['minfreq'][0], pylot_parameter['maxfreq'][0]],
|
'freq': [pylot_parameter['minfreq'][0], pylot_parameter['maxfreq'][0]],
|
||||||
'order': int(pylot_parameter['filter_order'][0])}
|
'order': int(pylot_parameter['filter_order'][0])}
|
||||||
@ -50,23 +64,46 @@ def readFilterInformation(pylot_parameter):
|
|||||||
|
|
||||||
|
|
||||||
def fit_curve(x, y):
|
def fit_curve(x, y):
|
||||||
|
"""
|
||||||
|
|
||||||
|
:param x: data points defining a curve y = f(x)
|
||||||
|
:type x: array_like
|
||||||
|
:param y: data points defining a curve y = f(x)
|
||||||
|
:type y: array_like
|
||||||
|
:return: tuple containing a function to evaluate a B-spline and
|
||||||
|
(the vector of knots, B-spline coefficients, degree of the spline)
|
||||||
|
:rtype: (func, (t, c, k))
|
||||||
|
"""
|
||||||
return splev, splrep(x, y)
|
return splev, splrep(x, y)
|
||||||
|
|
||||||
|
|
||||||
def getindexbounds(f, eta):
|
def getindexbounds(f, eta):
|
||||||
mi = f.argmax()
|
"""
|
||||||
m = max(f)
|
Get indices of values closest below and above maximum value in an array
|
||||||
b = m * eta
|
:param f: array
|
||||||
l = find_nearest(f[:mi], b)
|
:type f: `~numpy.ndarray`
|
||||||
u = find_nearest(f[mi:], b) + mi
|
:param eta: look for value in array that is closes to max_value * eta
|
||||||
|
:type eta: float
|
||||||
|
:return: tuple containing index of max value, index of value closest below max value,
|
||||||
|
index of value closest above max value
|
||||||
|
:rtype: (int, int, int)
|
||||||
|
"""
|
||||||
|
mi = f.argmax() # get indices of max values
|
||||||
|
m = max(f) # get maximum value
|
||||||
|
b = m * eta #
|
||||||
|
l = find_nearest(f[:mi], b) # find closest value below max value
|
||||||
|
u = find_nearest(f[mi:], b) + mi # find closest value above max value
|
||||||
return mi, l, u
|
return mi, l, u
|
||||||
|
|
||||||
|
|
||||||
def gen_Pool(ncores=0):
|
def gen_Pool(ncores=0):
|
||||||
'''
|
"""
|
||||||
|
Generate mulitprocessing pool object utilizing ncores amount of cores
|
||||||
:param ncores: number of CPU cores for multiprocessing.Pool, if ncores == 0 use all available
|
:param ncores: number of CPU cores for multiprocessing.Pool, if ncores == 0 use all available
|
||||||
|
:type ncores: int
|
||||||
:return: multiprocessing.Pool object
|
:return: multiprocessing.Pool object
|
||||||
'''
|
:rtype: `~multiprocessing.Pool`
|
||||||
|
"""
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
|
|
||||||
if ncores == 0:
|
if ncores == 0:
|
||||||
@ -79,14 +116,19 @@ def gen_Pool(ncores=0):
|
|||||||
|
|
||||||
|
|
||||||
def excludeQualityClasses(picks, qClasses, timeerrorsP, timeerrorsS):
|
def excludeQualityClasses(picks, qClasses, timeerrorsP, timeerrorsS):
|
||||||
'''
|
"""
|
||||||
takes PyLoT picks dictionary and returns a new dictionary with certain classes excluded.
|
takes PyLoT picks dictionary and returns a new dictionary with certain classes excluded.
|
||||||
:param picks: PyLoT picks dictionary
|
:param picks: PyLoT picks dictionary
|
||||||
|
:type picks: dict
|
||||||
:param qClasses: list (or int) of quality classes (0-4) to exclude
|
:param qClasses: list (or int) of quality classes (0-4) to exclude
|
||||||
:param timeerrorsP: time errors for classes (0-4) for P
|
:type qClasses: [int]
|
||||||
:param timeerrorsS: time errors for classes (0-4) for S
|
:param timeerrorsP: width of quality classes for P onsets in seconds
|
||||||
:return: new picks dictionary
|
:type timeerrorsP: (float, float, float, float)
|
||||||
'''
|
:param timeerrorsS: width of quality classes for S onsets in seconds
|
||||||
|
:type timeerrorsS: (float, float, float, float])
|
||||||
|
:return: dictionary containing only picks above the excluded quality class(es)
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
from pylot.core.pick.utils import getQualityFromUncertainty
|
from pylot.core.pick.utils import getQualityFromUncertainty
|
||||||
|
|
||||||
if type(qClasses) in [int, float]:
|
if type(qClasses) in [int, float]:
|
||||||
@ -114,9 +156,12 @@ def excludeQualityClasses(picks, qClasses, timeerrorsP, timeerrorsS):
|
|||||||
def clims(lim1, lim2):
|
def clims(lim1, lim2):
|
||||||
"""
|
"""
|
||||||
takes two pairs of limits and returns one pair of common limts
|
takes two pairs of limits and returns one pair of common limts
|
||||||
:param lim1:
|
:param lim1: limit 1
|
||||||
:param lim2:
|
:type lim1: int
|
||||||
:return:
|
:param lim2: limit 2
|
||||||
|
:type lim2: int
|
||||||
|
:return: new upper and lower limit common to both given limits
|
||||||
|
:rtype: [int, int]
|
||||||
|
|
||||||
>>> clims([0, 4], [1, 3])
|
>>> clims([0, 4], [1, 3])
|
||||||
[0, 4]
|
[0, 4]
|
||||||
@ -155,7 +200,7 @@ def demeanTrace(trace, window):
|
|||||||
demeaned within a certain time window
|
demeaned within a certain time window
|
||||||
:param trace: waveform trace object
|
:param trace: waveform trace object
|
||||||
:type trace: `~obspy.core.stream.Trace`
|
:type trace: `~obspy.core.stream.Trace`
|
||||||
:param window:
|
:param window: time window whitin which data is demeaned
|
||||||
:type window: tuple
|
:type window: tuple
|
||||||
:return: trace
|
:return: trace
|
||||||
:rtype: `~obspy.core.stream.Trace`
|
:rtype: `~obspy.core.stream.Trace`
|
||||||
@ -182,8 +227,11 @@ def find_in_list(list, str):
|
|||||||
takes a list of strings and a string and returns the first list item
|
takes a list of strings and a string and returns the first list item
|
||||||
matching the string pattern
|
matching the string pattern
|
||||||
:param list: list to search in
|
:param list: list to search in
|
||||||
|
:type list: list
|
||||||
:param str: pattern to search for
|
:param str: pattern to search for
|
||||||
|
:type str: str
|
||||||
:return: first list item containing pattern
|
:return: first list item containing pattern
|
||||||
|
:rtype: str
|
||||||
|
|
||||||
.. example::
|
.. example::
|
||||||
|
|
||||||
@ -208,13 +256,15 @@ def find_in_list(list, str):
|
|||||||
|
|
||||||
|
|
||||||
def find_nearest(array, value):
|
def find_nearest(array, value):
|
||||||
'''
|
"""
|
||||||
function find_nearest takes an array and a value and returns the
|
function find_nearest takes an array and a value and returns the
|
||||||
index of the nearest value found in the array
|
index of the nearest value found in the array
|
||||||
:param array: array containing values
|
:param array: array containing values
|
||||||
:type array: `~numpy.ndarray`
|
:type array: `~numpy.ndarray`
|
||||||
:param value: number searched for
|
:param value: number searched for
|
||||||
|
:type value: float
|
||||||
:return: index of the array item being nearest to the value
|
:return: index of the array item being nearest to the value
|
||||||
|
:rtype: int
|
||||||
|
|
||||||
>>> a = np.array([ 1.80339578, -0.72546654, 0.95769195, -0.98320759, 0.85922623])
|
>>> a = np.array([ 1.80339578, -0.72546654, 0.95769195, -0.98320759, 0.85922623])
|
||||||
>>> find_nearest(a, 1.3)
|
>>> find_nearest(a, 1.3)
|
||||||
@ -228,17 +278,18 @@ def find_nearest(array, value):
|
|||||||
>>> a = np.array([ 1.1, -0.7, 0.9, -0.9, 0.8])
|
>>> a = np.array([ 1.1, -0.7, 0.9, -0.9, 0.8])
|
||||||
>>> find_nearest(a, 0.849)
|
>>> find_nearest(a, 0.849)
|
||||||
4
|
4
|
||||||
'''
|
"""
|
||||||
return (np.abs(array - value)).argmin()
|
return (np.abs(array - value)).argmin()
|
||||||
|
|
||||||
|
|
||||||
def fnConstructor(s):
|
def fnConstructor(s):
|
||||||
'''
|
"""
|
||||||
takes a string and returns a valid filename (especially on windows machines)
|
takes a string and returns a valid filename (especially on windows machines)
|
||||||
:param s: desired filename
|
:param s: desired filename
|
||||||
:type s: str
|
:type s: str
|
||||||
:return: valid filename
|
:return: valid filename
|
||||||
'''
|
:rtype: str
|
||||||
|
"""
|
||||||
if type(s) is str:
|
if type(s) is str:
|
||||||
s = s.split(':')[-1]
|
s = s.split(':')[-1]
|
||||||
else:
|
else:
|
||||||
@ -255,6 +306,13 @@ def fnConstructor(s):
|
|||||||
|
|
||||||
|
|
||||||
def real_None(value):
|
def real_None(value):
|
||||||
|
"""
|
||||||
|
Convert "None" to None
|
||||||
|
:param value:
|
||||||
|
:type value: str, bool
|
||||||
|
:return:
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
if value == 'None':
|
if value == 'None':
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
@ -262,6 +320,13 @@ def real_None(value):
|
|||||||
|
|
||||||
|
|
||||||
def real_Bool(value):
|
def real_Bool(value):
|
||||||
|
"""
|
||||||
|
Convert string representations of bools to their true boolean value
|
||||||
|
:param value:
|
||||||
|
:type value: str, bool
|
||||||
|
:return: true boolean value
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
if value == 'True':
|
if value == 'True':
|
||||||
return True
|
return True
|
||||||
elif value == 'False':
|
elif value == 'False':
|
||||||
@ -276,7 +341,8 @@ def four_digits(year):
|
|||||||
from the last 100 years
|
from the last 100 years
|
||||||
:param year: two digit year
|
:param year: two digit year
|
||||||
:type year: int
|
:type year: int
|
||||||
:return: four digit year correspondant
|
:return: four digit year correspondent
|
||||||
|
:rtype: int
|
||||||
|
|
||||||
>>> four_digits(20)
|
>>> four_digits(20)
|
||||||
1920
|
1920
|
||||||
@ -293,13 +359,13 @@ def four_digits(year):
|
|||||||
|
|
||||||
|
|
||||||
def common_range(stream):
|
def common_range(stream):
|
||||||
'''
|
"""
|
||||||
takes a stream object and returns the earliest end and the latest start
|
takes a stream object and returns the earliest end and the latest start time of all contained trace objects
|
||||||
time of all contained trace objects
|
|
||||||
:param stream: seismological data stream
|
:param stream: seismological data stream
|
||||||
:type stream: `~obspy.core.stream.Stream`
|
:type stream: `~obspy.core.stream.Stream`
|
||||||
:return: maximum start time and minimum end time
|
:return: maximum start time and minimum end time
|
||||||
'''
|
:rtype: (`~maximum start time and minimum end time`, maximum start time and minimum end time)
|
||||||
|
"""
|
||||||
max_start = None
|
max_start = None
|
||||||
min_end = None
|
min_end = None
|
||||||
for trace in stream:
|
for trace in stream:
|
||||||
@ -311,13 +377,14 @@ def common_range(stream):
|
|||||||
|
|
||||||
|
|
||||||
def full_range(stream):
|
def full_range(stream):
|
||||||
'''
|
"""
|
||||||
takes a stream object and returns the latest end and the earliest start
|
takes a stream object and returns the latest end and the earliest start
|
||||||
time of all contained trace objects
|
time of all contained trace objects
|
||||||
:param stream: seismological data stream
|
:param stream: seismological data stream
|
||||||
:type stream: `~obspy.core.stream.Stream`
|
:type stream: `~obspy.core.stream.Stream`
|
||||||
:return: minimum start time and maximum end time
|
:return: minimum start time and maximum end time
|
||||||
'''
|
:rtype: (`~maximum start time and minimum end time`, maximum start time and minimum end time)
|
||||||
|
"""
|
||||||
min_start = min([trace.stats.starttime for trace in stream])
|
min_start = min([trace.stats.starttime for trace in stream])
|
||||||
max_end = max([trace.stats.endtime for trace in stream])
|
max_end = max([trace.stats.endtime for trace in stream])
|
||||||
|
|
||||||
@ -325,33 +392,35 @@ def full_range(stream):
|
|||||||
|
|
||||||
|
|
||||||
def getHash(time):
|
def getHash(time):
|
||||||
'''
|
"""
|
||||||
takes a time object and returns the corresponding SHA1 hash of the
|
takes a time object and returns the corresponding SHA1 hash of the formatted date string
|
||||||
formatted date string
|
|
||||||
:param time: time object for which a hash should be calculated
|
:param time: time object for which a hash should be calculated
|
||||||
:type time: :class: `~obspy.core.utcdatetime.UTCDateTime` object
|
:type time: `~obspy.core.utcdatetime.UTCDateTime`
|
||||||
:return: str
|
:return: SHA1 hash
|
||||||
'''
|
:rtype: str
|
||||||
|
"""
|
||||||
hg = hashlib.sha1()
|
hg = hashlib.sha1()
|
||||||
hg.update(time.strftime('%Y-%m-%d %H:%M:%S.%f'))
|
hg.update(time.strftime('%Y-%m-%d %H:%M:%S.%f'))
|
||||||
return hg.hexdigest()
|
return hg.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
def getLogin():
|
def getLogin():
|
||||||
'''
|
"""
|
||||||
returns the actual user's login ID
|
returns the actual user's login ID
|
||||||
:return: login ID
|
:return: login ID
|
||||||
'''
|
:rtype: str
|
||||||
|
"""
|
||||||
return os.getlogin()
|
return os.getlogin()
|
||||||
|
|
||||||
|
|
||||||
def getOwner(fn):
|
def getOwner(fn):
|
||||||
'''
|
"""
|
||||||
takes a filename and return the login ID of the actual owner of the file
|
takes a filename and return the login ID of the actual owner of the file
|
||||||
:param fn: filename of the file tested
|
:param fn: filename of the file tested
|
||||||
:type fn: str
|
:type fn: str
|
||||||
:return: login ID of the file's owner
|
:return: login ID of the file's owner
|
||||||
'''
|
:rtype: str
|
||||||
|
"""
|
||||||
system_name = platform.system()
|
system_name = platform.system()
|
||||||
if system_name in ["Linux", "Darwin"]:
|
if system_name in ["Linux", "Darwin"]:
|
||||||
import pwd
|
import pwd
|
||||||
@ -372,6 +441,8 @@ def getPatternLine(fn, pattern):
|
|||||||
:param pattern: pattern string to search for
|
:param pattern: pattern string to search for
|
||||||
:type pattern: str
|
:type pattern: str
|
||||||
:return: the complete line containing the pattern string or None
|
:return: the complete line containing the pattern string or None
|
||||||
|
:rtype: int, None
|
||||||
|
|
||||||
|
|
||||||
>>> getPatternLine('utils.py', 'python')
|
>>> getPatternLine('utils.py', 'python')
|
||||||
'#!/usr/bin/env python\\n'
|
'#!/usr/bin/env python\\n'
|
||||||
@ -393,18 +464,20 @@ def is_executable(fn):
|
|||||||
and False otherwise
|
and False otherwise
|
||||||
:param fn: path to the file to be tested
|
:param fn: path to the file to be tested
|
||||||
:return: True or False
|
:return: True or False
|
||||||
|
:rtype: bool
|
||||||
"""
|
"""
|
||||||
return os.path.isfile(fn) and os.access(fn, os.X_OK)
|
return os.path.isfile(fn) and os.access(fn, os.X_OK)
|
||||||
|
|
||||||
|
|
||||||
def isSorted(iterable):
|
def isSorted(iterable):
|
||||||
'''
|
"""
|
||||||
takes an iterable and returns 'True' if the items are in order otherwise
|
takes an iterable and returns True if the items are in order otherwise False
|
||||||
'False'
|
|
||||||
:param iterable: an iterable object
|
:param iterable: an iterable object
|
||||||
:type iterable:
|
:type iterable:
|
||||||
:return: Boolean
|
:return: Boolean
|
||||||
|
:rtype: bool
|
||||||
|
|
||||||
|
..example::
|
||||||
>>> isSorted(1)
|
>>> isSorted(1)
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
@ -417,7 +490,7 @@ def isSorted(iterable):
|
|||||||
False
|
False
|
||||||
>>> isSorted([2,3,1,4])
|
>>> isSorted([2,3,1,4])
|
||||||
False
|
False
|
||||||
'''
|
"""
|
||||||
assert isIterable(iterable), 'object is not iterable; object: {' \
|
assert isIterable(iterable), 'object is not iterable; object: {' \
|
||||||
'0}'.format(iterable)
|
'0}'.format(iterable)
|
||||||
if type(iterable) is str:
|
if type(iterable) is str:
|
||||||
@ -427,10 +500,12 @@ def isSorted(iterable):
|
|||||||
|
|
||||||
def isIterable(obj):
|
def isIterable(obj):
|
||||||
"""
|
"""
|
||||||
takes a python object and returns 'True' is the object is iterable and
|
takes a python object and returns True is the object is iterable and
|
||||||
'False' otherwise
|
False otherwise
|
||||||
:param obj: a python object
|
:param obj: a python object
|
||||||
|
:type obj: object
|
||||||
:return: True of False
|
:return: True of False
|
||||||
|
:rtype: bool
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
iterator = iter(obj)
|
iterator = iter(obj)
|
||||||
@ -447,6 +522,7 @@ def key_for_set_value(d):
|
|||||||
:type d: dict
|
:type d: dict
|
||||||
:return: key to the first non-False value found; None if no value's
|
:return: key to the first non-False value found; None if no value's
|
||||||
boolean equals True
|
boolean equals True
|
||||||
|
:rtype:
|
||||||
"""
|
"""
|
||||||
r = None
|
r = None
|
||||||
for k, v in d.items():
|
for k, v in d.items():
|
||||||
@ -456,13 +532,18 @@ def key_for_set_value(d):
|
|||||||
|
|
||||||
|
|
||||||
def prepTimeAxis(stime, trace, verbosity=0):
|
def prepTimeAxis(stime, trace, verbosity=0):
|
||||||
'''
|
"""
|
||||||
takes a starttime and a trace object and returns a valid time axis for
|
takes a starttime and a trace object and returns a valid time axis for
|
||||||
plotting
|
plotting
|
||||||
:param stime: start time of the actual seismogram as UTCDateTime
|
:param stime: start time of the actual seismogram as UTCDateTime
|
||||||
|
:type stime: `~obspy.core.utcdatetime.UTCDateTime`
|
||||||
:param trace: seismic trace object
|
:param trace: seismic trace object
|
||||||
|
:type trace: `~obspy.core.trace.Trace`
|
||||||
|
:param verbosity: if != 0, debug output will be written to console
|
||||||
|
:type verbosity: int
|
||||||
:return: valid numpy array with time stamps for plotting
|
:return: valid numpy array with time stamps for plotting
|
||||||
'''
|
:rtype: `~numpy.ndarray`
|
||||||
|
"""
|
||||||
nsamp = trace.stats.npts
|
nsamp = trace.stats.npts
|
||||||
srate = trace.stats.sampling_rate
|
srate = trace.stats.sampling_rate
|
||||||
tincr = trace.stats.delta
|
tincr = trace.stats.delta
|
||||||
@ -509,6 +590,20 @@ def find_horizontals(data):
|
|||||||
|
|
||||||
|
|
||||||
def make_pen(picktype, phase, key, quality):
|
def make_pen(picktype, phase, key, quality):
|
||||||
|
"""
|
||||||
|
Make PyQtGraph.QPen
|
||||||
|
:param picktype: 'manual' or 'automatic'
|
||||||
|
:type picktype: str
|
||||||
|
:param phase: 'P' or 'S'
|
||||||
|
:type phase: str
|
||||||
|
:param key: 'mpp', 'epp', 'lpp' or 'spe', (earliest/latest possible pick, symmetric picking error or
|
||||||
|
most probable pick)
|
||||||
|
:type key: str
|
||||||
|
:param quality: quality class of pick, decides color modifier
|
||||||
|
:type quality: int
|
||||||
|
:return: PyQtGraph QPen
|
||||||
|
:rtype: `~QPen`
|
||||||
|
"""
|
||||||
if pg:
|
if pg:
|
||||||
rgba = pick_color(picktype, phase, quality)
|
rgba = pick_color(picktype, phase, quality)
|
||||||
linestyle, width = pick_linestyle_pg(picktype, key)
|
linestyle, width = pick_linestyle_pg(picktype, key)
|
||||||
@ -517,8 +612,22 @@ def make_pen(picktype, phase, key, quality):
|
|||||||
|
|
||||||
|
|
||||||
def pick_color(picktype, phase, quality=0):
|
def pick_color(picktype, phase, quality=0):
|
||||||
|
"""
|
||||||
|
Create pick color by modifying the base color by the quality.
|
||||||
|
|
||||||
|
Returns rgba values in a range of [0, 255]. picktype, phase decide the base color,
|
||||||
|
quality decides the applied modifier
|
||||||
|
:param picktype: 'manual' or 'automatic'
|
||||||
|
:type picktype: str
|
||||||
|
:param phase: 'P' or 'S'
|
||||||
|
:type phase: str
|
||||||
|
:param quality: quality of pick. Decides the new intensity of the modifier color
|
||||||
|
:type quality: int
|
||||||
|
:return: tuple containing modified rgba color values
|
||||||
|
:rtype: (int, int, int, int)
|
||||||
|
"""
|
||||||
min_quality = 3
|
min_quality = 3
|
||||||
bpc = base_phase_colors(picktype, phase)
|
bpc = base_phase_colors(picktype, phase) # returns dict like {'modifier': 'g', 'rgba': (0, 0, 255, 255)}
|
||||||
rgba = bpc['rgba']
|
rgba = bpc['rgba']
|
||||||
modifier = bpc['modifier']
|
modifier = bpc['modifier']
|
||||||
intensity = 255.*quality/min_quality
|
intensity = 255.*quality/min_quality
|
||||||
@ -527,6 +636,20 @@ def pick_color(picktype, phase, quality=0):
|
|||||||
|
|
||||||
|
|
||||||
def pick_color_plt(picktype, phase, quality=0):
|
def pick_color_plt(picktype, phase, quality=0):
|
||||||
|
"""
|
||||||
|
Create pick color by modifying the base color by the quality.
|
||||||
|
|
||||||
|
Returns rgba values in a range of [0, 1]. picktype, phase decide the base color,
|
||||||
|
quality decides the applied modifier
|
||||||
|
:param picktype: 'manual' or 'automatic'
|
||||||
|
:type picktype: str
|
||||||
|
:param phase: 'P' or 'S'
|
||||||
|
:type phase: str
|
||||||
|
:param quality: quality of pick. Decides the new intensity of the modifier color
|
||||||
|
:type quality: int
|
||||||
|
:return: tuple containing rgba values matplotlib style, ranging from [0, 1]
|
||||||
|
:rtype: (float, float, float, float)
|
||||||
|
"""
|
||||||
rgba = list(pick_color(picktype, phase, quality))
|
rgba = list(pick_color(picktype, phase, quality))
|
||||||
for index, val in enumerate(rgba):
|
for index, val in enumerate(rgba):
|
||||||
rgba[index] /= 255.
|
rgba[index] /= 255.
|
||||||
@ -534,6 +657,16 @@ def pick_color_plt(picktype, phase, quality=0):
|
|||||||
|
|
||||||
|
|
||||||
def pick_linestyle_plt(picktype, key):
|
def pick_linestyle_plt(picktype, key):
|
||||||
|
"""
|
||||||
|
Get matplotlib line style for plotting by pick type and pick parameter (earliest/latest possible pick,
|
||||||
|
symmetric picking error or most probable pick).
|
||||||
|
:param picktype: 'manual' or 'automatic'
|
||||||
|
:type picktype: str
|
||||||
|
:param key: which pick parameter should be plotted, 'mpp', 'epp', 'lpp' or 'spe'
|
||||||
|
:type key: str
|
||||||
|
:return: tuple containing matplotlib line style string and line thicknes
|
||||||
|
:rtype: (str, float)
|
||||||
|
"""
|
||||||
linestyles_manu = {'mpp': ('solid', 2.),
|
linestyles_manu = {'mpp': ('solid', 2.),
|
||||||
'epp': ('dashed', 1.),
|
'epp': ('dashed', 1.),
|
||||||
'lpp': ('dashed', 1.),
|
'lpp': ('dashed', 1.),
|
||||||
@ -548,6 +681,16 @@ def pick_linestyle_plt(picktype, key):
|
|||||||
|
|
||||||
|
|
||||||
def pick_linestyle_pg(picktype, key):
|
def pick_linestyle_pg(picktype, key):
|
||||||
|
"""
|
||||||
|
Get Qt line style by picktype and pick parameter (earliest/latest possible pick, symmetric picking error or
|
||||||
|
most probable pick)
|
||||||
|
:param picktype: 'manual' or 'automatic'
|
||||||
|
:type picktype: str
|
||||||
|
:param key: which pick parameter should be plotted, 'mpp', 'epp', 'lpp' or 'spe'
|
||||||
|
:type key: str
|
||||||
|
:return: Qt line style parameters
|
||||||
|
:rtype:
|
||||||
|
"""
|
||||||
linestyles_manu = {'mpp': (QtCore.Qt.SolidLine, 2.),
|
linestyles_manu = {'mpp': (QtCore.Qt.SolidLine, 2.),
|
||||||
'epp': (QtCore.Qt.DashLine, 1.),
|
'epp': (QtCore.Qt.DashLine, 1.),
|
||||||
'lpp': (QtCore.Qt.DashLine, 1.),
|
'lpp': (QtCore.Qt.DashLine, 1.),
|
||||||
@ -562,6 +705,17 @@ def pick_linestyle_pg(picktype, key):
|
|||||||
|
|
||||||
|
|
||||||
def modify_rgba(rgba, modifier, intensity):
|
def modify_rgba(rgba, modifier, intensity):
|
||||||
|
"""
|
||||||
|
Modify rgba color by adding the given intensity to the modifier color
|
||||||
|
:param rgba: tuple containing rgba values
|
||||||
|
:type rgba: (int, int, int, int)
|
||||||
|
:param modifier: which color should be modified, eg. 'r', 'g', 'b'
|
||||||
|
:type modifier: str
|
||||||
|
:param intensity: intensity to be added to selected color
|
||||||
|
:type intensity: float
|
||||||
|
:return: tuple containing rgba values
|
||||||
|
:rtype: (int, int, int, int)
|
||||||
|
"""
|
||||||
rgba = list(rgba)
|
rgba = list(rgba)
|
||||||
index = {'r': 0,
|
index = {'r': 0,
|
||||||
'g': 1,
|
'g': 1,
|
||||||
@ -576,10 +730,28 @@ def modify_rgba(rgba, modifier, intensity):
|
|||||||
|
|
||||||
|
|
||||||
def base_phase_colors(picktype, phase):
|
def base_phase_colors(picktype, phase):
|
||||||
|
"""
|
||||||
|
Get base color for a phase from style settings
|
||||||
|
:param picktype: 'manual' or 'automatic' picks
|
||||||
|
:type picktype: str
|
||||||
|
:param phase: Phase to select color for, 'P' or 'S'
|
||||||
|
:type phase: str
|
||||||
|
:return: dictionary {'modifier': 'g', 'rgba': (0, 0, 255, 255)}
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
phasecolors = style_settings.phasecolors
|
phasecolors = style_settings.phasecolors
|
||||||
return phasecolors[picktype][phase]
|
return phasecolors[picktype][phase]
|
||||||
|
|
||||||
def transform_colors_mpl_str(colors, no_alpha=False):
|
def transform_colors_mpl_str(colors, no_alpha=False):
|
||||||
|
"""
|
||||||
|
Transforms rgba color values to a matplotlib string of color values with a range of [0, 1]
|
||||||
|
:param colors: tuple of rgba color values ranging from [0, 255]
|
||||||
|
:type colors: (float, float, float, float)
|
||||||
|
:param no_alpha: Wether to return a alpha value in the matplotlib color string
|
||||||
|
:type no_alpha: bool
|
||||||
|
:return: String containing r, g, b values and alpha value if no_alpha is False (default)
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
colors = list(colors)
|
colors = list(colors)
|
||||||
colors_mpl = tuple([color / 255. for color in colors])
|
colors_mpl = tuple([color / 255. for color in colors])
|
||||||
if no_alpha:
|
if no_alpha:
|
||||||
@ -589,6 +761,13 @@ def transform_colors_mpl_str(colors, no_alpha=False):
|
|||||||
return colors_mpl
|
return colors_mpl
|
||||||
|
|
||||||
def transform_colors_mpl(colors):
|
def transform_colors_mpl(colors):
|
||||||
|
"""
|
||||||
|
Transform rgba colors from [0, 255] to [0, 1]
|
||||||
|
:param colors: tuple of rgba color values ranging from [0, 255]
|
||||||
|
:type colors: (float, float, float, float)
|
||||||
|
:return: tuple of rgba color values ranging from [0, 1]
|
||||||
|
:rtype: (float, float, float, float)
|
||||||
|
"""
|
||||||
colors = list(colors)
|
colors = list(colors)
|
||||||
colors_mpl = tuple([color / 255. for color in colors])
|
colors_mpl = tuple([color / 255. for color in colors])
|
||||||
return colors_mpl
|
return colors_mpl
|
||||||
@ -596,10 +775,11 @@ def transform_colors_mpl(colors):
|
|||||||
def remove_underscores(data):
|
def remove_underscores(data):
|
||||||
"""
|
"""
|
||||||
takes a `obspy.core.stream.Stream` object and removes all underscores
|
takes a `obspy.core.stream.Stream` object and removes all underscores
|
||||||
from stationnames
|
from station names
|
||||||
:param data: stream of seismic data
|
:param data: stream of seismic data
|
||||||
:type data: `obspy.core.stream.Stream`
|
:type data: `~obspy.core.stream.Stream`
|
||||||
:return: data stream
|
:return: data stream
|
||||||
|
:rtype: `~obspy.core.stream.Stream`
|
||||||
"""
|
"""
|
||||||
for tr in data:
|
for tr in data:
|
||||||
# remove underscores
|
# remove underscores
|
||||||
@ -608,16 +788,17 @@ def remove_underscores(data):
|
|||||||
|
|
||||||
|
|
||||||
def trim_station_components(data, trim_start=True, trim_end=True):
|
def trim_station_components(data, trim_start=True, trim_end=True):
|
||||||
'''
|
"""
|
||||||
cut a stream so only the part common to all three traces is kept to avoid dealing with offsets
|
cut a stream so only the part common to all three traces is kept to avoid dealing with offsets
|
||||||
:param data: stream of seismic data
|
:param data: stream of seismic data
|
||||||
:type data: `obspy.core.stream.Stream`
|
:type data: `~obspy.core.stream.Stream`
|
||||||
:param trim_start: trim start of stream
|
:param trim_start: trim start of stream
|
||||||
:type trim_start: bool
|
:type trim_start: bool
|
||||||
:param trim_end: trim end of stream
|
:param trim_end: trim end of stream
|
||||||
:type trim_end: bool
|
:type trim_end: bool
|
||||||
:return: data stream
|
:return: data stream
|
||||||
'''
|
:rtype: `~obspy.core.stream.Stream`
|
||||||
|
"""
|
||||||
starttime = {False: None}
|
starttime = {False: None}
|
||||||
endtime = {False: None}
|
endtime = {False: None}
|
||||||
|
|
||||||
@ -635,11 +816,13 @@ def trim_station_components(data, trim_start=True, trim_end=True):
|
|||||||
|
|
||||||
|
|
||||||
def check4gaps(data):
|
def check4gaps(data):
|
||||||
'''
|
"""
|
||||||
check for gaps in Stream and remove them
|
check for gaps in Stream and remove them
|
||||||
:param data: stream of seismic data
|
:param data: stream of seismic data
|
||||||
|
:type data: `~obspy.core.stream.Stream`
|
||||||
:return: data stream
|
:return: data stream
|
||||||
'''
|
:rtype: `~obspy.core.stream.Stream`
|
||||||
|
"""
|
||||||
stations = get_stations(data)
|
stations = get_stations(data)
|
||||||
|
|
||||||
for station in stations:
|
for station in stations:
|
||||||
@ -653,11 +836,13 @@ def check4gaps(data):
|
|||||||
|
|
||||||
|
|
||||||
def check4doubled(data):
|
def check4doubled(data):
|
||||||
'''
|
"""
|
||||||
check for doubled stations for same channel in Stream and take only the first one
|
check for doubled stations for same channel in Stream and take only the first one
|
||||||
:param data: stream of seismic data
|
:param data: stream of seismic data
|
||||||
|
:type data: `~obspy.core.stream.Stream`
|
||||||
:return: data stream
|
:return: data stream
|
||||||
'''
|
:rtype: `~obspy.core.stream.Stream`
|
||||||
|
"""
|
||||||
stations = get_stations(data)
|
stations = get_stations(data)
|
||||||
|
|
||||||
for station in stations:
|
for station in stations:
|
||||||
@ -678,6 +863,13 @@ def check4doubled(data):
|
|||||||
|
|
||||||
|
|
||||||
def get_stations(data):
|
def get_stations(data):
|
||||||
|
"""
|
||||||
|
Get list of all station names in data stream
|
||||||
|
:param data: stream containing seismic traces
|
||||||
|
:type data: `~obspy.core.stream.Stream`
|
||||||
|
:return: list of all station names in data, no duplicates
|
||||||
|
:rtype: list of str
|
||||||
|
"""
|
||||||
stations = []
|
stations = []
|
||||||
for tr in data:
|
for tr in data:
|
||||||
station = tr.stats.station
|
station = tr.stats.station
|
||||||
@ -688,14 +880,35 @@ def get_stations(data):
|
|||||||
|
|
||||||
|
|
||||||
def check4rotated(data, metadata=None, verbosity=1):
|
def check4rotated(data, metadata=None, verbosity=1):
|
||||||
|
"""
|
||||||
|
|
||||||
|
:param data: stream object containing seismic traces
|
||||||
|
:type data: `~obspy.core.stream.Stream`
|
||||||
|
:param metadata: tuple containing metadata type string and metadata parser object
|
||||||
|
:type metadata: (str, `~obspy.io.xseed.parser.Parser`)
|
||||||
|
:param verbosity: if 0 print no information at runtime
|
||||||
|
:type verbosity: int
|
||||||
|
:return: stream object with traditionally oriented traces (ZNE) for stations that had misaligned traces (123) before
|
||||||
|
:rtype: `~obspy.core.stream.Stream`
|
||||||
|
"""
|
||||||
|
|
||||||
def rotate_components(wfstream, metadata=None):
|
def rotate_components(wfstream, metadata=None):
|
||||||
"""rotates components if orientation code is numeric.
|
"""
|
||||||
azimut and dip are fetched from metadata"""
|
Rotate components if orientation code is numeric (= non traditional orientation).
|
||||||
|
|
||||||
|
Azimut and dip are fetched from metadata. To be rotated, traces of a station have to be cut to the same length.
|
||||||
|
Returns unrotated traces of no metadata is provided
|
||||||
|
:param wfstream: stream containing seismic traces
|
||||||
|
:type wfstream: `~obspy.core.stream.Stream`
|
||||||
|
:param metadata: tuple containing metadata type string and metadata parser object
|
||||||
|
:type metadata: (str, `~obspy.io.xseed.parser.Parser`)
|
||||||
|
:return: stream object with traditionally oriented traces (ZNE)
|
||||||
|
:rtype: `~obspy.core.stream.Stream`
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
# indexing fails if metadata is None
|
# indexing fails if metadata is None
|
||||||
metadata[0]
|
metadata[0]
|
||||||
except:
|
except TypeError:
|
||||||
if verbosity:
|
if verbosity:
|
||||||
msg = 'Warning: could not rotate traces since no metadata was given\nset Inventory file!'
|
msg = 'Warning: could not rotate traces since no metadata was given\nset Inventory file!'
|
||||||
print(msg)
|
print(msg)
|
||||||
@ -710,7 +923,15 @@ def check4rotated(data, metadata=None, verbosity=1):
|
|||||||
parser = metadata[1]
|
parser = metadata[1]
|
||||||
|
|
||||||
def get_dip_azimut(parser, trace_id):
|
def get_dip_azimut(parser, trace_id):
|
||||||
"""gets azimut and dip for a trace out of the metadata parser"""
|
"""
|
||||||
|
Gets azimuth and dip by trace id out of the metadata parser
|
||||||
|
:param parser: metadata parser object
|
||||||
|
:type parser: `~obspy.io.xseed.parser.Parser`
|
||||||
|
:param trace_id: eg. 'BW.RJOB..EHZ',
|
||||||
|
:type trace_id: str
|
||||||
|
:return: tuple containing dip and azimuth of the trace corresponding to trace_id
|
||||||
|
:rtype: (float, float)
|
||||||
|
"""
|
||||||
dip = None
|
dip = None
|
||||||
azimut = None
|
azimut = None
|
||||||
try:
|
try:
|
||||||
@ -731,7 +952,7 @@ def check4rotated(data, metadata=None, verbosity=1):
|
|||||||
|
|
||||||
trace_ids = [trace.id for trace in wfstream]
|
trace_ids = [trace.id for trace in wfstream]
|
||||||
for trace_id in trace_ids:
|
for trace_id in trace_ids:
|
||||||
orientation = trace_id[-1]
|
orientation = trace_id[-1] # last letter if trace id is orientation code, ZNE or 123
|
||||||
if orientation.isnumeric():
|
if orientation.isnumeric():
|
||||||
# misaligned channels have a number as orientation
|
# misaligned channels have a number as orientation
|
||||||
azimuts = []
|
azimuts = []
|
||||||
@ -751,7 +972,7 @@ def check4rotated(data, metadata=None, verbosity=1):
|
|||||||
wfstream[1], azimuts[1], dips[1],
|
wfstream[1], azimuts[1], dips[1],
|
||||||
wfstream[2], azimuts[2], dips[2])
|
wfstream[2], azimuts[2], dips[2])
|
||||||
print('check4rotated: rotated station {} to ZNE'.format(trace_id))
|
print('check4rotated: rotated station {} to ZNE'.format(trace_id))
|
||||||
z_index = dips.index(min(dips)) # get z-trace index (dip is measured from 0 to -90
|
z_index = dips.index(min(dips)) # get z-trace index (dip is measured from 0 to -90)
|
||||||
wfstream[z_index].data = z
|
wfstream[z_index].data = z
|
||||||
wfstream[z_index].stats.channel = wfstream[z_index].stats.channel[0:-1] + 'Z'
|
wfstream[z_index].stats.channel = wfstream[z_index].stats.channel[0:-1] + 'Z'
|
||||||
del trace_ids[z_index]
|
del trace_ids[z_index]
|
||||||
@ -771,9 +992,9 @@ def check4rotated(data, metadata=None, verbosity=1):
|
|||||||
|
|
||||||
stations = get_stations(data)
|
stations = get_stations(data)
|
||||||
|
|
||||||
for station in stations:
|
for station in stations: # loop through all stations and rotate data if neccessary
|
||||||
wf_station = data.select(station=station)
|
wf_station = data.select(station=station)
|
||||||
wf_station = rotate_components(wf_station, metadata)
|
rotate_components(wf_station, metadata)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
@ -833,7 +1054,9 @@ def which(program, infile=None):
|
|||||||
takes a program name and returns the full path to the executable or None
|
takes a program name and returns the full path to the executable or None
|
||||||
modified after: http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python
|
modified after: http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python
|
||||||
:param program: name of the desired external program
|
:param program: name of the desired external program
|
||||||
|
:type program: str
|
||||||
:return: full path of the executable file
|
:return: full path of the executable file
|
||||||
|
:rtype: str
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
from PySide.QtCore import QSettings
|
from PySide.QtCore import QSettings
|
||||||
@ -876,14 +1099,16 @@ def which(program, infile=None):
|
|||||||
|
|
||||||
|
|
||||||
def loopIdentifyPhase(phase):
|
def loopIdentifyPhase(phase):
|
||||||
'''
|
"""
|
||||||
Loop through phase string and try to recognize its type (P or S wave).
|
Loop through phase string and try to recognize its type (P or S wave).
|
||||||
Global variable ALTSUFFIX gives alternative suffix for phases if they do not end with P, p or S, s.
|
Global variable ALTSUFFIX gives alternative suffix for phases if they do not end with P, p or S, s.
|
||||||
If ALTSUFFIX is not given, the function will cut the last letter of the phase string until string ends
|
If ALTSUFFIX is not given, the function will cut the last letter of the phase string until string ends
|
||||||
with P or S.
|
with P or S.
|
||||||
:param phase: phase name (str)
|
:param phase: phase name
|
||||||
:return:
|
:type phase: str
|
||||||
'''
|
:return: str of phase ending with identified type, None if phase could not be identified
|
||||||
|
:rtype: str or None
|
||||||
|
"""
|
||||||
from pylot.core.util.defaults import ALTSUFFIX
|
from pylot.core.util.defaults import ALTSUFFIX
|
||||||
|
|
||||||
phase_copy = phase
|
phase_copy = phase
|
||||||
@ -902,11 +1127,13 @@ def loopIdentifyPhase(phase):
|
|||||||
|
|
||||||
|
|
||||||
def identifyPhase(phase):
|
def identifyPhase(phase):
|
||||||
'''
|
"""
|
||||||
Returns capital P or S if phase string is identified by last letter. Else returns False.
|
Returns capital P or S if phase string is identified by last letter. Else returns False.
|
||||||
:param phase: phase name (str)
|
:param phase: phase name
|
||||||
|
:type phase: str
|
||||||
:return: 'P', 'S' or False
|
:return: 'P', 'S' or False
|
||||||
'''
|
:rtype: str or bool
|
||||||
|
"""
|
||||||
# common phase suffix for P and S
|
# common phase suffix for P and S
|
||||||
common_P = ['P', 'p']
|
common_P = ['P', 'p']
|
||||||
common_S = ['S', 's']
|
common_S = ['S', 's']
|
||||||
@ -919,10 +1146,24 @@ def identifyPhase(phase):
|
|||||||
|
|
||||||
|
|
||||||
def identifyPhaseID(phase):
|
def identifyPhaseID(phase):
|
||||||
|
"""
|
||||||
|
Returns phase id (capital P or S)
|
||||||
|
:param phase: phase name
|
||||||
|
:type phase: str
|
||||||
|
:return: phase type string
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
return identifyPhase(loopIdentifyPhase(phase))
|
return identifyPhase(loopIdentifyPhase(phase))
|
||||||
|
|
||||||
|
|
||||||
def has_spe(pick):
|
def has_spe(pick):
|
||||||
|
"""
|
||||||
|
Check for 'spe' key (symmetric picking error) in dict and return its value if found, else return None
|
||||||
|
:param pick: pick dictionary
|
||||||
|
:type pick: dict
|
||||||
|
:return: value of 'spe' key
|
||||||
|
:rtype: float or None
|
||||||
|
"""
|
||||||
if not 'spe' in pick.keys():
|
if not 'spe' in pick.keys():
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
|
Loading…
Reference in New Issue
Block a user