[update] first version write html output, todo: html parameters argparse?
This commit is contained in:
parent
64daf34941
commit
7a6072f8dd
@ -1,5 +1,6 @@
|
|||||||
# Parameters file for Surveillance Bot
|
# Parameters file for Surveillance Bot
|
||||||
datapath: '/data/SDS/' # SC3 Datapath
|
datapath: '/data/SDS/' # SC3 Datapath
|
||||||
|
outpath_html: '/home/marcel/tmp/survBot_out.html' # output of HTML table
|
||||||
networks: ['1Y', 'HA']
|
networks: ['1Y', 'HA']
|
||||||
stations: '*'
|
stations: '*'
|
||||||
locations: '*'
|
locations: '*'
|
||||||
|
@ -8,6 +8,7 @@ ulimit -s 8192
|
|||||||
##$ -q "*@minos15"
|
##$ -q "*@minos15"
|
||||||
|
|
||||||
export PYTHONPATH="$PYTHONPATH:/home/marcel/git/"
|
export PYTHONPATH="$PYTHONPATH:/home/marcel/git/"
|
||||||
|
export PYTHONPATH="$PYTHONPATH:/home/marcel/git/code_base/"
|
||||||
|
|
||||||
source /opt/anaconda3/etc/profile.d/conda.sh
|
source /opt/anaconda3/etc/profile.d/conda.sh
|
||||||
conda activate py37
|
conda activate py37
|
||||||
|
31
survBot.py
31
survBot.py
@ -13,11 +13,14 @@ import numpy as np
|
|||||||
from obspy import read, UTCDateTime, Stream
|
from obspy import read, UTCDateTime, Stream
|
||||||
from obspy.clients.filesystem.sds import Client
|
from obspy.clients.filesystem.sds import Client
|
||||||
|
|
||||||
|
from write_utils import get_print_title_str
|
||||||
|
|
||||||
pjoin = os.path.join
|
pjoin = os.path.join
|
||||||
UP = "\x1B[{length}A"
|
UP = "\x1B[{length}A"
|
||||||
CLR = "\x1B[0K"
|
CLR = "\x1B[0K"
|
||||||
deg_str = '\N{DEGREE SIGN}C'
|
deg_str = '\N{DEGREE SIGN}C'
|
||||||
|
|
||||||
|
|
||||||
def read_yaml(file_path):
|
def read_yaml(file_path):
|
||||||
with open(file_path, "r") as f:
|
with open(file_path, "r") as f:
|
||||||
return yaml.safe_load(f)
|
return yaml.safe_load(f)
|
||||||
@ -30,7 +33,7 @@ def nsl_from_id(st_id):
|
|||||||
|
|
||||||
def get_st_id(trace):
|
def get_st_id(trace):
|
||||||
stats = trace.stats
|
stats = trace.stats
|
||||||
return f'{stats.network}.{stats.station}.'#{stats.location}'
|
return f'{stats.network}.{stats.station}.' # {stats.location}'
|
||||||
|
|
||||||
|
|
||||||
def fancy_timestr(dt, thresh=600, modif='+'):
|
def fancy_timestr(dt, thresh=600, modif='+'):
|
||||||
@ -60,7 +63,7 @@ class SurveillanceBot(object):
|
|||||||
self.print_count = 0
|
self.print_count = 0
|
||||||
self.refresh_period = 0
|
self.refresh_period = 0
|
||||||
|
|
||||||
self.cl = Client(self.parameters.get('datapath')) #TODO: Check if this has to be loaded again on update
|
self.cl = Client(self.parameters.get('datapath')) # TODO: Check if this has to be loaded again on update
|
||||||
self.get_stations()
|
self.get_stations()
|
||||||
|
|
||||||
def transform_parameters(self):
|
def transform_parameters(self):
|
||||||
@ -99,7 +102,7 @@ class SurveillanceBot(object):
|
|||||||
for location in locations:
|
for location in locations:
|
||||||
for channel in channels:
|
for channel in channels:
|
||||||
self.filenames += list(self.cl._get_filenames(network, station, location, channel,
|
self.filenames += list(self.cl._get_filenames(network, station, location, channel,
|
||||||
starttime=t1, endtime=time_now))
|
starttime=t1, endtime=time_now))
|
||||||
|
|
||||||
def read_data(self):
|
def read_data(self):
|
||||||
self.data = {}
|
self.data = {}
|
||||||
@ -183,11 +186,13 @@ class SurveillanceBot(object):
|
|||||||
if len(times) > 0:
|
if len(times) > 0:
|
||||||
return min(times)
|
return min(times)
|
||||||
|
|
||||||
|
def print_analysis_html(self, filename):
|
||||||
|
with open(filename, 'w') as outfile:
|
||||||
|
pass
|
||||||
|
|
||||||
def print_analysis(self):
|
def print_analysis(self):
|
||||||
timespan = self.parameters.get('timespan') * 24 * 3600
|
self.print(200 * '+')
|
||||||
self.print(200*'+')
|
title_str = get_print_title_str(self.parameters)
|
||||||
tdelta_str = str(timedelta(seconds=int(timespan)))
|
|
||||||
title_str = f'Analysis table of router quality within the last {tdelta_str}'
|
|
||||||
self.print(title_str)
|
self.print(title_str)
|
||||||
if self.refresh_period > 0:
|
if self.refresh_period > 0:
|
||||||
self.print(f'Refreshing every {self.refresh_period}s.')
|
self.print(f'Refreshing every {self.refresh_period}s.')
|
||||||
@ -224,8 +229,8 @@ class SurveillanceBot(object):
|
|||||||
n_nl = string.count('\n')
|
n_nl = string.count('\n')
|
||||||
string.replace('\n', clear_end)
|
string.replace('\n', clear_end)
|
||||||
print(string, end=clear_end, **kwargs)
|
print(string, end=clear_end, **kwargs)
|
||||||
self.print_count += n_nl + 1 #number of newlines + actual print with end='\n' (no check for kwargs end!)
|
self.print_count += n_nl + 1 # number of newlines + actual print with end='\n' (no check for kwargs end!)
|
||||||
#print('pc:', self.print_count)
|
# print('pc:', self.print_count)
|
||||||
|
|
||||||
def clear_prints(self):
|
def clear_prints(self):
|
||||||
print(UP.format(length=self.print_count), end='')
|
print(UP.format(length=self.print_count), end='')
|
||||||
@ -300,7 +305,7 @@ class StationQC(object):
|
|||||||
|
|
||||||
def analyse_channels(self):
|
def analyse_channels(self):
|
||||||
if self.verbosity > 0:
|
if self.verbosity > 0:
|
||||||
self.print(150*'#')
|
self.print(150 * '#')
|
||||||
self.print('This is StationQT. Calculating quality for station'
|
self.print('This is StationQT. Calculating quality for station'
|
||||||
' {network}.{station}.{location}'.format(**self.nsl))
|
' {network}.{station}.{location}'.format(**self.nsl))
|
||||||
self.voltage_analysis()
|
self.voltage_analysis()
|
||||||
@ -333,7 +338,7 @@ class StationQC(object):
|
|||||||
|
|
||||||
def voltage_analysis(self, channel='VEI'):
|
def voltage_analysis(self, channel='VEI'):
|
||||||
""" Analyse voltage channel for over/undervoltage """
|
""" Analyse voltage channel for over/undervoltage """
|
||||||
key='voltage'
|
key = 'voltage'
|
||||||
st = self.stream.select(channel=channel)
|
st = self.stream.select(channel=channel)
|
||||||
trace = self.get_trace(st, key)
|
trace = self.get_trace(st, key)
|
||||||
if not trace: return
|
if not trace: return
|
||||||
@ -367,7 +372,7 @@ class StationQC(object):
|
|||||||
|
|
||||||
def pb_temp_analysis(self, channel='EX1'):
|
def pb_temp_analysis(self, channel='EX1'):
|
||||||
""" Analyse PowBox temperature output. """
|
""" Analyse PowBox temperature output. """
|
||||||
key='temp'
|
key = 'temp'
|
||||||
st = self.stream.select(channel=channel)
|
st = self.stream.select(channel=channel)
|
||||||
trace = self.get_trace(st, key)
|
trace = self.get_trace(st, key)
|
||||||
if not trace: return
|
if not trace: return
|
||||||
@ -375,7 +380,7 @@ class StationQC(object):
|
|||||||
thresholds = self.parameters.get('THRESHOLDS')
|
thresholds = self.parameters.get('THRESHOLDS')
|
||||||
temp = 20. * voltage - 20
|
temp = 20. * voltage - 20
|
||||||
# average temp
|
# average temp
|
||||||
timespan = min([self.parameters.get('timespan') * 24 * 3600, int(len(temp)/trace.stats.sampling_rate)])
|
timespan = min([self.parameters.get('timespan') * 24 * 3600, int(len(temp) / trace.stats.sampling_rate)])
|
||||||
nsamp_av = int(trace.stats.sampling_rate) * timespan
|
nsamp_av = int(trace.stats.sampling_rate) * timespan
|
||||||
av_temp_str = str(round(np.mean(temp[-nsamp_av:]), 1)) + deg_str
|
av_temp_str = str(round(np.mean(temp[-nsamp_av:]), 1)) + deg_str
|
||||||
# dt of average
|
# dt of average
|
||||||
|
@ -9,7 +9,7 @@ __author__ = 'Marcel Paffrath'
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
from datetime import timedelta
|
import argparse
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from PySide2 import QtGui, QtCore, QtWidgets
|
from PySide2 import QtGui, QtCore, QtWidgets
|
||||||
@ -34,6 +34,7 @@ else:
|
|||||||
from obspy import UTCDateTime
|
from obspy import UTCDateTime
|
||||||
|
|
||||||
from survBot import SurveillanceBot
|
from survBot import SurveillanceBot
|
||||||
|
from write_utils import *
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from rest_api.utils import get_station_iccid
|
from rest_api.utils import get_station_iccid
|
||||||
@ -95,6 +96,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||||||
# init some attributes
|
# init some attributes
|
||||||
self.dt_thresh = dt_thresh
|
self.dt_thresh = dt_thresh
|
||||||
self.last_mouse_loc = None
|
self.last_mouse_loc = None
|
||||||
|
self.status_message = ''
|
||||||
self.starttime = UTCDateTime()
|
self.starttime = UTCDateTime()
|
||||||
|
|
||||||
# setup main layout of the GUI
|
# setup main layout of the GUI
|
||||||
@ -181,6 +183,41 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||||||
self.last_mouse_loc = event.pos()
|
self.last_mouse_loc = event.pos()
|
||||||
return super(QtWidgets.QMainWindow, self).eventFilter(object, event)
|
return super(QtWidgets.QMainWindow, self).eventFilter(object, event)
|
||||||
|
|
||||||
|
def write_html_table(self):
|
||||||
|
fnout = self.parameters.get('outpath_html')
|
||||||
|
if not fnout:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
with open(fnout, 'w') as outfile:
|
||||||
|
write_html_header(outfile)
|
||||||
|
#write_html_table_title(outfile, self.parameters)
|
||||||
|
init_html_table(outfile)
|
||||||
|
nrows = self.table.rowCount()
|
||||||
|
ncolumns = self.table.columnCount()
|
||||||
|
|
||||||
|
# add header item 0 fix default black bg color for headers
|
||||||
|
station_header = QtWidgets.QTableWidgetItem(text='Station')
|
||||||
|
station_header.setText('Station')
|
||||||
|
header_items = [station_header]
|
||||||
|
for column in range(ncolumns):
|
||||||
|
hheader = self.table.horizontalHeaderItem(column)
|
||||||
|
header_items.append(hheader)
|
||||||
|
write_html_row(outfile, header_items, html_key='th')
|
||||||
|
|
||||||
|
for row in range(nrows):
|
||||||
|
vheader = self.table.verticalHeaderItem(row)
|
||||||
|
col_items = [vheader]
|
||||||
|
for column in range(ncolumns):
|
||||||
|
col_items.append(self.table.item(row, column))
|
||||||
|
write_html_row(outfile, col_items)
|
||||||
|
|
||||||
|
finish_html_table(outfile)
|
||||||
|
write_html_text(outfile, self.status_message)
|
||||||
|
write_html_footer(outfile)
|
||||||
|
except Exception as e:
|
||||||
|
print(f'Could not write HTML table to {fnout}:')
|
||||||
|
print(e)
|
||||||
|
|
||||||
def sms_context_menu(self, row_ind):
|
def sms_context_menu(self, row_ind):
|
||||||
""" Open a context menu when left-clicking vertical header item """
|
""" Open a context menu when left-clicking vertical header item """
|
||||||
header_item = self.table.verticalHeaderItem(row_ind)
|
header_item = self.table.verticalHeaderItem(row_ind)
|
||||||
@ -225,11 +262,13 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||||||
|
|
||||||
def fill_status_bar(self):
|
def fill_status_bar(self):
|
||||||
""" Set status bar text """
|
""" Set status bar text """
|
||||||
status_bar = self.statusBar()
|
|
||||||
timespan = timedelta(seconds=int(self.parameters.get('timespan') * 24 * 3600))
|
timespan = timedelta(seconds=int(self.parameters.get('timespan') * 24 * 3600))
|
||||||
status_bar.showMessage(f'Program starttime (UTC) {self.starttime.strftime("%Y-%m-%d %H:%M:%S")} | '
|
self.status_message = f'Program starttime (UTC) {self.starttime.strftime("%Y-%m-%d %H:%M:%S")} | ' \
|
||||||
f'Refresh period: {self.refresh_period}s | '
|
f'Current time (UTC) {UTCDateTime().strftime("%Y-%m-%d %H:%M:%S")} | ' \
|
||||||
f'Showing data of last {timespan}')
|
f'Refresh period: {self.refresh_period}s | '\
|
||||||
|
f'Showing data of last {timespan}'
|
||||||
|
status_bar = self.statusBar()
|
||||||
|
status_bar.showMessage(self.status_message)
|
||||||
|
|
||||||
def fill_table(self):
|
def fill_table(self):
|
||||||
""" Fills the table with most recent information. Executed after execute_qc thread is done or on refresh. """
|
""" Fills the table with most recent information. Executed after execute_qc thread is done or on refresh. """
|
||||||
@ -291,6 +330,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||||||
|
|
||||||
# table filling/refreshing done, set clear_on_refresh to False
|
# table filling/refreshing done, set clear_on_refresh to False
|
||||||
self.clear_on_refresh = False
|
self.clear_on_refresh = False
|
||||||
|
# write html output if parameter is set
|
||||||
|
self.write_html_table()
|
||||||
|
|
||||||
def get_time_delay_color(self, dt):
|
def get_time_delay_color(self, dt):
|
||||||
""" Set color of time delay after thresholds specified in self.dt_thresh """
|
""" Set color of time delay after thresholds specified in self.dt_thresh """
|
||||||
|
48
write_utils.py
Normal file
48
write_utils.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
def write_html_table_title(fobj, parameters):
|
||||||
|
title = get_print_title_str(parameters)
|
||||||
|
fobj.write(f'<h3>{title}</h3>\n')
|
||||||
|
|
||||||
|
def write_html_text(fobj, text):
|
||||||
|
fobj.write(f'<p>{text}</p>\n')
|
||||||
|
|
||||||
|
def write_html_header(fobj):
|
||||||
|
header = ['<!DOCTYPE html>',
|
||||||
|
'<html>',
|
||||||
|
'<style>',
|
||||||
|
'table, th, td {',
|
||||||
|
'border:1px solid black;',
|
||||||
|
'}',
|
||||||
|
'</style>',
|
||||||
|
'<body>']
|
||||||
|
for item in header:
|
||||||
|
fobj.write(item + '\n')
|
||||||
|
|
||||||
|
def init_html_table(fobj):
|
||||||
|
fobj.write('<table style="width:100%">\n')
|
||||||
|
|
||||||
|
def finish_html_table(fobj):
|
||||||
|
fobj.write('</table>\n')
|
||||||
|
|
||||||
|
def write_html_footer(fobj):
|
||||||
|
footer = ['</body>',
|
||||||
|
'</html>']
|
||||||
|
for item in footer:
|
||||||
|
fobj.write(item + '\n')
|
||||||
|
|
||||||
|
def write_html_row(fobj, items, html_key='td'):
|
||||||
|
fobj.write('<tr>\n')
|
||||||
|
for item in items:
|
||||||
|
text = item.text()
|
||||||
|
color = item.backgroundColor().name()
|
||||||
|
# fix for black background of headers
|
||||||
|
color = '#e6e6e6' if color == '#000000' else color
|
||||||
|
fobj.write(f'<{html_key} bgcolor="{color}">' + text + f'</{html_key}>\n')
|
||||||
|
fobj.write('</tr>\n')
|
||||||
|
|
||||||
|
def get_print_title_str(parameters):
|
||||||
|
timespan = parameters.get('timespan') * 24 * 3600
|
||||||
|
tdelta_str = str(timedelta(seconds=int(timespan)))
|
||||||
|
return f'Analysis table of router quality within the last {tdelta_str}'
|
||||||
|
|
Loading…
Reference in New Issue
Block a user