2022-11-08 16:45:21 +01:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
import matplotlib
|
|
|
|
|
2022-11-21 15:31:32 +01:00
|
|
|
|
2022-11-08 16:45:21 +01:00
|
|
|
def get_bg_color(check_key, status, dt_thresh=None, hex=False):
|
2022-11-15 17:19:39 +01:00
|
|
|
message = status.message
|
2022-11-08 16:45:21 +01:00
|
|
|
if check_key == 'last active':
|
2022-11-15 17:19:39 +01:00
|
|
|
bg_color = get_time_delay_color(message, dt_thresh)
|
2022-11-08 16:45:21 +01:00
|
|
|
elif check_key == 'temp':
|
2022-11-15 17:19:39 +01:00
|
|
|
bg_color = get_temp_color(message)
|
2022-11-08 16:45:21 +01:00
|
|
|
else:
|
2022-11-15 17:19:39 +01:00
|
|
|
if status.is_warn:
|
|
|
|
bg_color = get_color('WARNX')(status.count)
|
|
|
|
elif status.is_error:
|
|
|
|
bg_color = get_color('FAIL')
|
2022-11-08 16:45:21 +01:00
|
|
|
else:
|
2022-11-15 17:19:39 +01:00
|
|
|
bg_color = get_color(message)
|
2022-11-08 16:45:21 +01:00
|
|
|
if not bg_color:
|
|
|
|
bg_color = get_color('undefined')
|
|
|
|
|
|
|
|
if hex:
|
|
|
|
bg_color = '#{:02x}{:02x}{:02x}'.format(*bg_color[:3])
|
|
|
|
return bg_color
|
|
|
|
|
2022-11-21 15:31:32 +01:00
|
|
|
|
2022-11-08 16:45:21 +01:00
|
|
|
def get_color(key):
|
|
|
|
# some GUI default colors
|
|
|
|
colors_dict = {'FAIL': (255, 50, 0, 255),
|
|
|
|
'NO DATA': (255, 255, 125, 255),
|
2022-11-15 17:19:39 +01:00
|
|
|
'WARN': (255, 255, 80, 255),
|
|
|
|
'WARNX': lambda x: (min([255, 200 + x ** 2]), 255, 80, 255),
|
2022-11-08 16:45:21 +01:00
|
|
|
'OK': (125, 255, 125, 255),
|
|
|
|
'undefined': (230, 230, 230, 255)}
|
|
|
|
return colors_dict.get(key)
|
|
|
|
|
2022-11-21 15:31:32 +01:00
|
|
|
|
2022-11-08 16:45:21 +01:00
|
|
|
def get_time_delay_color(dt, dt_thresh):
|
|
|
|
""" Set color of time delay after thresholds specified in self.dt_thresh """
|
|
|
|
if dt < dt_thresh[0]:
|
|
|
|
return get_color('OK')
|
|
|
|
elif dt_thresh[0] <= dt < dt_thresh[1]:
|
|
|
|
return get_color('WARN')
|
|
|
|
return get_color('FAIL')
|
|
|
|
|
2022-11-21 15:31:32 +01:00
|
|
|
|
2022-11-08 16:45:21 +01:00
|
|
|
def get_temp_color(temp, vmin=-10, vmax=60, cmap='coolwarm'):
|
|
|
|
""" Get an rgba temperature value back from specified cmap, linearly interpolated between vmin and vmax. """
|
|
|
|
if type(temp) in [str]:
|
|
|
|
return get_color('undefined')
|
|
|
|
cmap = matplotlib.cm.get_cmap(cmap)
|
|
|
|
val = (temp - vmin) / (vmax - vmin)
|
|
|
|
rgba = [int(255 * c) for c in cmap(val)]
|
|
|
|
return rgba
|
|
|
|
|
2022-11-21 15:31:32 +01:00
|
|
|
|
|
|
|
def modify_stream_for_plot(st, parameters):
|
|
|
|
""" copy (if necessary) and modify stream for plotting """
|
|
|
|
ch_units = parameters.get('CHANNEL_UNITS')
|
|
|
|
ch_transf = parameters.get('CHANNEL_TRANSFORM')
|
|
|
|
|
|
|
|
# if either of both are defined make copy
|
|
|
|
if ch_units or ch_transf:
|
|
|
|
st = st.copy()
|
|
|
|
|
|
|
|
# modify trace for plotting by multiplying unit factor (e.g. 1e-3 mV to V)
|
|
|
|
if ch_units:
|
|
|
|
for tr in st:
|
|
|
|
channel = tr.stats.channel
|
|
|
|
unit_factor = ch_units.get(channel)
|
|
|
|
if unit_factor:
|
|
|
|
tr.data = tr.data * float(unit_factor)
|
|
|
|
# modify trace for plotting by other arithmetic expressions
|
|
|
|
if ch_transf:
|
|
|
|
for tr in st:
|
|
|
|
channel = tr.stats.channel
|
|
|
|
transf = ch_transf.get(channel)
|
|
|
|
if transf:
|
|
|
|
tr.data = transform_trace(tr.data, transf)
|
|
|
|
|
|
|
|
return st
|
|
|
|
|
|
|
|
|
|
|
|
def transform_trace(data, transf):
|
|
|
|
"""
|
|
|
|
Transform trace with arithmetic operations in order, specified in transf
|
|
|
|
@param data: numpy array
|
|
|
|
@param transf: list of lists with arithmetic operations (e.g. [['*', '20'], ] -> multiply data by 20
|
|
|
|
"""
|
|
|
|
# This looks a little bit hardcoded, however it is safer than using e.g. "eval"
|
|
|
|
for operator_str, val in transf:
|
|
|
|
if operator_str == '+':
|
|
|
|
data = data + val
|
|
|
|
elif operator_str == '-':
|
|
|
|
data = data - val
|
|
|
|
elif operator_str == '*':
|
|
|
|
data = data * val
|
|
|
|
elif operator_str == '/':
|
|
|
|
data = data / val
|
|
|
|
else:
|
|
|
|
raise IOError(f'Unknown arithmethic operator string: {operator_str}')
|
|
|
|
|
|
|
|
return data
|
2022-11-22 14:20:22 +01:00
|
|
|
|
|
|
|
|
2022-12-02 11:15:37 +01:00
|
|
|
def trace_ylabels(fig, parameters, verbosity=0):
|
2022-11-22 14:20:22 +01:00
|
|
|
"""
|
|
|
|
Adds channel names to y-axis if defined in parameters.
|
|
|
|
Can get mixed up if channel order in stream and channel names defined in parameters.yaml differ, but it is
|
|
|
|
difficult to assess the correct order from Obspy plotting routing.
|
|
|
|
"""
|
|
|
|
names = parameters.get('channel_names')
|
|
|
|
if not names: # or not len(st.traces):
|
|
|
|
return
|
|
|
|
if not len(names) == len(fig.axes):
|
|
|
|
if verbosity:
|
|
|
|
print('Mismatch in axis and label lengths. Not adding plot labels')
|
|
|
|
return
|
|
|
|
for channel_name, ax in zip(names, fig.axes):
|
|
|
|
if channel_name:
|
|
|
|
ax.set_ylabel(channel_name)
|
|
|
|
|
|
|
|
|
2022-12-02 11:15:37 +01:00
|
|
|
def trace_yticks(fig, parameters, verbosity=0):
|
|
|
|
"""
|
|
|
|
Adds channel names to y-axis if defined in parameters.
|
|
|
|
Can get mixed up if channel order in stream and channel names defined in parameters.yaml differ, but it is
|
|
|
|
difficult to assess the correct order from Obspy plotting routing.
|
|
|
|
"""
|
|
|
|
ticks = parameters.get('CHANNEL_TICKS')
|
|
|
|
if not ticks:
|
|
|
|
return
|
|
|
|
if not len(ticks) == len(fig.axes):
|
|
|
|
if verbosity:
|
|
|
|
print('Mismatch in axis tick and label lengths. Not changing plot ticks.')
|
|
|
|
return
|
|
|
|
for ytick_tripple, ax in zip(ticks, fig.axes):
|
|
|
|
if not ytick_tripple:
|
|
|
|
continue
|
|
|
|
ymin, ymax, step = ytick_tripple
|
|
|
|
|
|
|
|
yticks = list(range(ymin, ymax + step, step))
|
|
|
|
ax.set_yticks(yticks)
|
|
|
|
ax.set_ylim(ymin - step, ymax + step)
|