Compare commits
3 Commits
03616a2b7b
...
a89ea1b06d
Author | SHA1 | Date | |
---|---|---|---|
a89ea1b06d | |||
24d15d9d55 | |||
bc70dc0816 |
47
survBot.py
47
survBot.py
@ -469,12 +469,14 @@ class SurveillanceBot(object):
|
|||||||
|
|
||||||
|
|
||||||
class StationQC(object):
|
class StationQC(object):
|
||||||
def __init__(self, parent, stream, nsl, parameters, keys, starttime, verbosity, print_func, status_track={}):
|
def __init__(self, parent, stream, nsl, parameters, keys, starttime, verbosity, print_func, status_track=None):
|
||||||
"""
|
"""
|
||||||
Station Quality Check class.
|
Station Quality Check class.
|
||||||
:param nsl: dictionary containing network, station and location (key: str)
|
:param nsl: dictionary containing network, station and location (key: str)
|
||||||
:param parameters: parameters dictionary from parameters.yaml file
|
:param parameters: parameters dictionary from parameters.yaml file
|
||||||
"""
|
"""
|
||||||
|
if status_track is None:
|
||||||
|
status_track = {}
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.stream = stream
|
self.stream = stream
|
||||||
self.nsl = nsl
|
self.nsl = nsl
|
||||||
@ -721,6 +723,15 @@ class StationQC(object):
|
|||||||
def return_analysis(self):
|
def return_analysis(self):
|
||||||
return self.status_dict
|
return self.status_dict
|
||||||
|
|
||||||
|
def get_unit_factor(self, channel):
|
||||||
|
""" Get channel multiplier for unit from parameters. If none is specified return 1 """
|
||||||
|
channel_params = self.parameters.get('CHANNELS').get(channel)
|
||||||
|
if channel_params:
|
||||||
|
multiplier = channel_params.get('unit')
|
||||||
|
if multiplier:
|
||||||
|
return float(multiplier)
|
||||||
|
return 1
|
||||||
|
|
||||||
def get_last_occurrence_timestring(self, trace, indices):
|
def get_last_occurrence_timestring(self, trace, indices):
|
||||||
""" returns a nicely formatted string of the timedelta since program starttime and occurrence and abs time"""
|
""" returns a nicely formatted string of the timedelta since program starttime and occurrence and abs time"""
|
||||||
last_occur = self.get_last_occurrence(trace, indices)
|
last_occur = self.get_last_occurrence(trace, indices)
|
||||||
@ -739,44 +750,44 @@ class StationQC(object):
|
|||||||
trace = self.get_trace(st, key)
|
trace = self.get_trace(st, key)
|
||||||
if not trace:
|
if not trace:
|
||||||
return
|
return
|
||||||
clockQuality = trace.data
|
clock_quality = trace.data
|
||||||
clockQuality_warn_level = self.parameters.get('THRESHOLDS').get('clockquality_warn')
|
clock_quality_warn_level = self.parameters.get('THRESHOLDS').get('clockquality_warn')
|
||||||
clockQuality_fail_level = self.parameters.get('THRESHOLDS').get('clockquality_fail')
|
clock_quality_fail_level = self.parameters.get('THRESHOLDS').get('clockquality_fail')
|
||||||
|
|
||||||
if self.verbosity > 1:
|
if self.verbosity > 1:
|
||||||
self.print(40 * '-')
|
self.print(40 * '-')
|
||||||
self.print('Performing Clock Quality check', flush=False)
|
self.print('Performing Clock Quality check', flush=False)
|
||||||
|
|
||||||
clockQuality_warn = np.where(clockQuality < clockQuality_warn_level)[0]
|
clockQuality_warn = np.where(clock_quality < clock_quality_warn_level)[0]
|
||||||
clockQuality_fail = np.where(clockQuality < clockQuality_fail_level)[0]
|
clockQuality_fail = np.where(clock_quality < clock_quality_fail_level)[0]
|
||||||
|
|
||||||
if len(clockQuality_warn) == 0 and len(clockQuality_fail) == 0:
|
if len(clockQuality_warn) == 0 and len(clockQuality_fail) == 0:
|
||||||
self.status_ok(key, detailed_message=f'ClockQuality={(clockQuality[-1])}')
|
self.status_ok(key, detailed_message=f'ClockQuality={(clock_quality[-1])}')
|
||||||
return
|
return
|
||||||
|
|
||||||
last_val_average = np.nanmean(clockQuality[-n_sample_average:])
|
last_val_average = np.nanmean(clock_quality[-n_sample_average:])
|
||||||
|
|
||||||
# keep OK status if there are only minor warnings (lower warn level)
|
# keep OK status if there are only minor warnings (lower warn level)
|
||||||
warn_message = f'Trace {trace.get_id()}:'
|
warn_message = f'Trace {trace.get_id()}:'
|
||||||
if len(clockQuality_warn) > 0:
|
if len(clockQuality_warn) > 0:
|
||||||
# try calculate number of warn peaks from gaps between indices
|
# try calculate number of warn peaks from gaps between indices
|
||||||
n_qc_warn = self.calc_occurrences(clockQuality_warn)
|
n_qc_warn = self.calc_occurrences(clockQuality_warn)
|
||||||
detailed_message = warn_message + f' {n_qc_warn}x Clock quality less then {clockQuality_warn_level}%' \
|
detailed_message = warn_message + f' {n_qc_warn}x Clock quality less then {clock_quality_warn_level}%' \
|
||||||
+ self.get_last_occurrence_timestring(trace, clockQuality_warn)
|
+ self.get_last_occurrence_timestring(trace, clockQuality_warn)
|
||||||
self.status_ok(key, detailed_message=detailed_message)
|
self.status_ok(key, detailed_message=detailed_message)
|
||||||
|
|
||||||
# set WARN status for sever warnings in the past
|
# set WARN status for severe warnings in the past
|
||||||
if len(clockQuality_fail) > 0:
|
if len(clockQuality_fail) > 0:
|
||||||
# try calculate number of fail peaks from gaps between indices
|
# try calculate number of fail peaks from gaps between indices
|
||||||
n_qc_fail = self.calc_occurrences(clockQuality_fail)
|
n_qc_fail = self.calc_occurrences(clockQuality_fail)
|
||||||
detailed_message = warn_message + f' {n_qc_fail}x Clock quality less then {clockQuality_fail_level}%' \
|
detailed_message = warn_message + f' {n_qc_fail}x Clock quality less then {clock_quality_fail_level}%' \
|
||||||
+ self.get_last_occurrence_timestring(trace, clockQuality_fail)
|
+ self.get_last_occurrence_timestring(trace, clockQuality_fail)
|
||||||
self.warn(key, detailed_message=detailed_message, count=n_qc_fail,
|
self.warn(key, detailed_message=detailed_message, count=n_qc_fail,
|
||||||
last_occurrence=self.get_last_occurrence(trace, clockQuality_fail))
|
last_occurrence=self.get_last_occurrence(trace, clockQuality_fail))
|
||||||
|
|
||||||
# set FAIL state if last value is less than fail level
|
# set FAIL state if last value is less than fail level
|
||||||
if last_val_average < clockQuality_fail_level:
|
if last_val_average < clock_quality_fail_level:
|
||||||
self.error(key, detailed_message=f'ClockQuality={(clockQuality[-1])}')
|
self.error(key, detailed_message=f'ClockQuality={(clock_quality[-1])}')
|
||||||
|
|
||||||
def voltage_analysis(self, channel='VEI'):
|
def voltage_analysis(self, channel='VEI'):
|
||||||
""" Analyse voltage channel for over/undervoltage """
|
""" Analyse voltage channel for over/undervoltage """
|
||||||
@ -785,7 +796,7 @@ class StationQC(object):
|
|||||||
trace = self.get_trace(st, key)
|
trace = self.get_trace(st, key)
|
||||||
if not trace:
|
if not trace:
|
||||||
return
|
return
|
||||||
voltage = trace.data * 1e-3
|
voltage = trace.data * self.get_unit_factor(channel)
|
||||||
low_volt = self.parameters.get('THRESHOLDS').get('low_volt')
|
low_volt = self.parameters.get('THRESHOLDS').get('low_volt')
|
||||||
high_volt = self.parameters.get('THRESHOLDS').get('high_volt')
|
high_volt = self.parameters.get('THRESHOLDS').get('high_volt')
|
||||||
|
|
||||||
@ -824,7 +835,7 @@ class StationQC(object):
|
|||||||
trace = self.get_trace(st, key)
|
trace = self.get_trace(st, key)
|
||||||
if not trace:
|
if not trace:
|
||||||
return
|
return
|
||||||
voltage = trace.data * 1e-6
|
voltage = trace.data * self.get_unit_factor(channel)
|
||||||
thresholds = self.parameters.get('THRESHOLDS')
|
thresholds = self.parameters.get('THRESHOLDS')
|
||||||
temp = 20. * voltage - 20
|
temp = 20. * voltage - 20
|
||||||
# average temp
|
# average temp
|
||||||
@ -870,7 +881,7 @@ class StationQC(object):
|
|||||||
|
|
||||||
# correct for channel unit
|
# correct for channel unit
|
||||||
for trace in st:
|
for trace in st:
|
||||||
trace.data = trace.data * 1e-6 # TODO: Here and elsewhere: hardcoded, change this?
|
trace.data = trace.data * self.get_unit_factor(trace.stats.channel)
|
||||||
|
|
||||||
# calculate average of absolute maximum of mass offset of last n_samp_mean
|
# calculate average of absolute maximum of mass offset of last n_samp_mean
|
||||||
last_values = np.array([trace.data[-n_samp_mean:] for trace in st])
|
last_values = np.array([trace.data[-n_samp_mean:] for trace in st])
|
||||||
@ -908,7 +919,7 @@ class StationQC(object):
|
|||||||
if not trace:
|
if not trace:
|
||||||
return
|
return
|
||||||
|
|
||||||
voltage = trace.data * 1e-6
|
voltage = trace.data * self.get_unit_factor(channel)
|
||||||
if self.verbosity > 1:
|
if self.verbosity > 1:
|
||||||
self.print(40 * '-')
|
self.print(40 * '-')
|
||||||
self.print('Performing PowBox 12V/230V check (EX2)', flush=False)
|
self.print('Performing PowBox 12V/230V check (EX2)', flush=False)
|
||||||
@ -931,7 +942,7 @@ class StationQC(object):
|
|||||||
if not trace:
|
if not trace:
|
||||||
return
|
return
|
||||||
|
|
||||||
voltage = trace.data * 1e-6
|
voltage = trace.data * self.get_unit_factor(channel)
|
||||||
if self.verbosity > 1:
|
if self.verbosity > 1:
|
||||||
self.print(40 * '-')
|
self.print(40 * '-')
|
||||||
self.print('Performing PowBox Router/Charger check (EX3)', flush=False)
|
self.print('Performing PowBox Router/Charger check (EX3)', flush=False)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user