From 1929e3ac7944be304b15fba11b97547e4a19cc67 Mon Sep 17 00:00:00 2001 From: Lan Dam <ldam@passcal.nmt.edu> Date: Wed, 2 Aug 2023 15:42:08 -0600 Subject: [PATCH] combine get wf plot info to get chan plot info --- sohstationviewer/database/extract_data.py | 47 ++---- sohstationviewer/database/soh.db | Bin 61440 -> 61440 bytes .../multi_threaded_plotting_widget.py | 29 ++-- .../view/plotting/state_of_health_widget.py | 6 - .../plotting/time_power_squared_dialog.py | 4 +- .../view/plotting/waveform_dialog.py | 6 - tests/test_database/test_extract_data.py | 137 +++++++++++------- 7 files changed, 110 insertions(+), 119 deletions(-) diff --git a/sohstationviewer/database/extract_data.py b/sohstationviewer/database/extract_data.py index 684a8456d..cf0ab6208 100755 --- a/sohstationviewer/database/extract_data.py +++ b/sohstationviewer/database/extract_data.py @@ -5,7 +5,7 @@ from sohstationviewer.database.process_db import execute_db_dict, execute_db from sohstationviewer.conf.dbSettings import dbConf -def get_chan_plot_info(org_chan_id: str, chan_info: Dict, data_type: str, +def get_chan_plot_info(org_chan_id: str, data_type: str, color_mode: ColorMode = 'B') -> Dict: """ Given chanID read from raw data file and detected dataType @@ -24,10 +24,10 @@ def get_chan_plot_info(org_chan_id: str, chan_info: Dict, data_type: str, chan = 'VM?' if org_chan_id.startswith('MassPos'): chan = 'MassPos?' + if org_chan_id.startswith('DS'): + chan = 'SEISMIC' if org_chan_id.startswith('Event DS'): chan = 'Event DS?' - if org_chan_id.startswith('DS') and 'DSP' not in org_chan_id: - chan = 'DS?' if org_chan_id.startswith('Disk Usage'): chan = 'Disk Usage?' if dbConf['seisRE'].match(chan): @@ -46,17 +46,13 @@ def get_chan_plot_info(org_chan_id: str, chan_info: Dict, data_type: str, sql = (f"{o_sql} WHERE channel='{chan}' and C.param=P.param" f" and dataType='{data_type}'") chan_db_info = execute_db_dict(sql) - + seismic_label = None if len(chan_db_info) == 0: chan_db_info = execute_db_dict( f"{o_sql} WHERE channel='DEFAULT' and C.param=P.param") else: if chan_db_info[0]['channel'] == 'SEISMIC': - try: - chan_db_info[0]['label'] = dbConf['seisLabel'][org_chan_id[-1]] - except KeyError: - chan_db_info[0]['label'] = str(chan_info['samplerate']) - + seismic_label = get_seismic_chan_label(org_chan_id) chan_db_info[0]['channel'] = org_chan_id chan_db_info[0]['label'] = ( @@ -68,6 +64,8 @@ def get_chan_plot_info(org_chan_id: str, chan_info: Dict, data_type: str, else chan_db_info[0]['fixPoint']) if chan_db_info[0]['label'].strip() == '': chan_db_info[0]['label'] = chan_db_info[0]['channel'] + elif seismic_label is not None: + chan_db_info[0]['label'] = seismic_label else: chan_db_info[0]['label'] = '-'.join([chan_db_info[0]['channel'], chan_db_info[0]['label']]) @@ -76,29 +74,6 @@ def get_chan_plot_info(org_chan_id: str, chan_info: Dict, data_type: str, return chan_db_info[0] -def get_wf_plot_info(org_chan_id: str, *args, **kwargs) -> Dict: - """ - :param org_chan_id: channel name read from data source - :param chan_info: to be compliant with get_chan_plot_info() - :param data_type: to be compliant with get_chan_plot_info() - :param color_mode: to be compliant with get_chan_plot_info() - :return info of channel read from DB which is used for plotting - """ - # Waveform plot's color is fixed to NULL in the database, so we do not need - # to get the valueColors columns from the database. - chan_info = execute_db_dict( - "SELECT param, plotType, height " - "FROM Parameters WHERE param='Seismic data'") - # The plotting API still requires that the key 'valueColors' is mapped to - # something, so we are setting it to None. - chan_info[0]['valueColors'] = None - chan_info[0]['label'] = get_chan_label(org_chan_id) - chan_info[0]['unit'] = '' - chan_info[0]['channel'] = 'SEISMIC' - chan_info[0]['convertFactor'] = 1 - return chan_info[0] - - def get_convert_factor(chan_id, data_type): sql = f"SELECT convertFactor FROM Channels WHERE channel='{chan_id}' " \ f"AND dataType='{data_type}'" @@ -109,7 +84,13 @@ def get_convert_factor(chan_id, data_type): return None -def get_chan_label(chan_id): +def get_seismic_chan_label(chan_id): + """ + Get label for chan_id in which data stream can use chan_id for label while + other seismic need to add coordinate to chan_id for label + :param chan_id: name of channel + :return label: label to put in front of the plot of the channel + """ if chan_id.startswith("DS"): label = chan_id else: diff --git a/sohstationviewer/database/soh.db b/sohstationviewer/database/soh.db index e705fa6ba04f1b7c745e28769bc6dc5dccb82a53..824a36a094470e5b29fe5e0caf3a60b4138ac3eb 100755 GIT binary patch delta 176 zcmZp8z})bFd4d!Zv&TdkCm^{oK|7wOJf)!6z%s{-fq_A0qNBv-_3<$YjB7XZ9Qe-2 z7`B<^P#dplSWt+eu>nwlEQ2}&CqJjSZ-BjTVsWuTL4I*&NoIatS&$+Vr!<2q11AH6 zc(AKyu&<}{=KbfR1SU&A@MYq^zB%JT2EPFpBT!#Zh#-r!I3rXM*kC3x7Ikq>=bUVX PfQ-cAR0Y?fBCt3BrF$`1 delta 175 zcmZp8z})bFd4d!Z<MxR%PC#;Ff_6MlReqLXaawu_0|SH1L`R9u>*He*7&mU_Iq;p4 zv1~KTp*CLAvY-${V*{W9MFw>SPJT{t-vE2x#NuLwg8bsllFa-(hyqzAPGJUB22KVB zahG8G&HK+s2{7KCEb+i^bH;-Vegi&6pf<2c%)BhZ;*3BwU>=hgi@G?cb56EGKt^J5 Ls)B1#5m+1mMTIfh diff --git a/sohstationviewer/view/plotting/plotting_widget/multi_threaded_plotting_widget.py b/sohstationviewer/view/plotting/plotting_widget/multi_threaded_plotting_widget.py index 229544d77..2ef180480 100644 --- a/sohstationviewer/view/plotting/plotting_widget/multi_threaded_plotting_widget.py +++ b/sohstationviewer/view/plotting/plotting_widget/multi_threaded_plotting_widget.py @@ -1,6 +1,6 @@ # Define functions to call processor -from typing import Tuple, Union, Dict, Callable, List, Optional +from typing import Tuple, Union, Dict, List from PySide2 import QtCore @@ -105,20 +105,17 @@ class MultiThreadedPlottingWidget(PlottingWidget): return True def create_plotting_channel_processors( - self, plotting_data: Dict, - get_plot_info: Optional[Callable[[str, Dict, str], Dict]]) -> None: + self, plotting_data: Dict, need_db_info: bool = False) -> None: """ Create a data processor for each channel data. :param plotting_data: dict of data by chan_id - :param get_plot_info: function to get plotting info from database + :param need_db_info: flag to get db info """ for chan_id in plotting_data: - if get_plot_info is not None: - chan_db_info = get_plot_info(chan_id, - plotting_data[chan_id], - self.parent.data_type, - self.c_mode) + if need_db_info: + chan_db_info = get_chan_plot_info( + chan_id, self.parent.data_type, self.c_mode) if chan_db_info['height'] == 0: # not draw continue @@ -196,16 +193,10 @@ class MultiThreadedPlottingWidget(PlottingWidget): self.clean_up() self.finished.emit() return - self.create_plotting_channel_processors( - self.plotting_data1, self.get_plot_info) - self.create_plotting_channel_processors( - self.plotting_data2, get_chan_plot_info) + self.create_plotting_channel_processors(self.plotting_data1, True) + self.create_plotting_channel_processors(self.plotting_data2, True) self.process_channel() - def get_plot_info(self, *args, **kwargs): - # function to get database info for channels in self.plotting_data1 - pass - @QtCore.Slot() def process_channel(self, channel_data=None, channel_id=None): """ @@ -347,6 +338,6 @@ class MultiThreadedPlottingWidget(PlottingWidget): self.is_working = True start_msg = 'Zooming in...' display_tracking_info(self.tracking_box, start_msg, 'info') - self.create_plotting_channel_processors(self.plotting_data1, None) - self.create_plotting_channel_processors(self.plotting_data2, None) + self.create_plotting_channel_processors(self.plotting_data1) + self.create_plotting_channel_processors(self.plotting_data2) self.process_channel() diff --git a/sohstationviewer/view/plotting/state_of_health_widget.py b/sohstationviewer/view/plotting/state_of_health_widget.py index 4269c0e29..ae7bfabfe 100644 --- a/sohstationviewer/view/plotting/state_of_health_widget.py +++ b/sohstationviewer/view/plotting/state_of_health_widget.py @@ -8,8 +8,6 @@ from sohstationviewer.controller.util import apply_convert_factor from sohstationviewer.model.data_type_model import DataTypeModel -from sohstationviewer.database.extract_data import get_chan_plot_info - from sohstationviewer.view.util.enums import LogType from sohstationviewer.view.plotting.plotting_widget.\ multi_threaded_plotting_widget import MultiThreadedPlottingWidget @@ -52,10 +50,6 @@ class SOHWidget(MultiThreadedPlottingWidget): self.processing_log.append((msg, LogType.WARNING)) return True - def get_plot_info(self, *args, **kwargs): - # function to get database info for soh channels in self.plotting_data1 - return get_chan_plot_info(*args, **kwargs) - def plot_single_channel(self, c_data: Dict, chan_id: str): """ Plot the channel chan_id. diff --git a/sohstationviewer/view/plotting/time_power_squared_dialog.py b/sohstationviewer/view/plotting/time_power_squared_dialog.py index dbdaa82f5..f27f3c436 100755 --- a/sohstationviewer/view/plotting/time_power_squared_dialog.py +++ b/sohstationviewer/view/plotting/time_power_squared_dialog.py @@ -13,7 +13,7 @@ from sohstationviewer.controller.util import ( display_tracking_info, add_thousand_separator, ) from sohstationviewer.database.extract_data import ( - get_color_def, get_color_ranges, get_chan_label, + get_color_def, get_color_ranges, get_seismic_chan_label, ) from sohstationviewer.model.data_type_model import DataTypeModel from sohstationviewer.model.handling_data import ( @@ -227,7 +227,7 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget): ax.spines[['right', 'left', 'top', 'bottom']].set_visible(False) ax.text( -0.12, 1, - f"{get_chan_label(chan_id)} {c_data['samplerate']}sps", + f"{get_seismic_chan_label(chan_id)} {c_data['samplerate']}sps", horizontalalignment='left', verticalalignment='top', rotation='horizontal', diff --git a/sohstationviewer/view/plotting/waveform_dialog.py b/sohstationviewer/view/plotting/waveform_dialog.py index 8a161ab29..11d07c262 100755 --- a/sohstationviewer/view/plotting/waveform_dialog.py +++ b/sohstationviewer/view/plotting/waveform_dialog.py @@ -11,8 +11,6 @@ from sohstationviewer.view.plotting.plotting_widget.\ from sohstationviewer.controller.util import apply_convert_factor -from sohstationviewer.database.extract_data import get_wf_plot_info - class WaveformWidget(MultiThreadedPlottingWidget): """ @@ -39,10 +37,6 @@ class WaveformWidget(MultiThreadedPlottingWidget): return super().init_plot(d_obj, data_time, key, start_tm, end_tm, time_ticks_total, is_waveform=True) - def get_plot_info(self, *args, **kwargs): - # function to get database info for wf channels in self.plotting_data1 - return get_wf_plot_info(*args, **kwargs) - def plot_single_channel(self, c_data: Dict, chan_id: str): """ Plot the channel chan_id. diff --git a/tests/test_database/test_extract_data.py b/tests/test_database/test_extract_data.py index 64e7e1da1..418ea9775 100644 --- a/tests/test_database/test_extract_data.py +++ b/tests/test_database/test_extract_data.py @@ -2,8 +2,7 @@ import unittest from sohstationviewer.database.extract_data import ( get_chan_plot_info, - get_wf_plot_info, - get_chan_label, + get_seismic_chan_label, get_signature_channels, get_color_def, get_color_ranges, @@ -11,7 +10,7 @@ from sohstationviewer.database.extract_data import ( class TestExtractData(unittest.TestCase): - def test_get_chan_plot_info_good_channel_and_data_type(self): + def test_get_chan_plot_info_good_soh_channel_and_data_type(self): """ Test basic functionality of get_chan_plot_info - channel and data type combination exists in database table `Channels` @@ -25,9 +24,62 @@ class TestExtractData(unittest.TestCase): 'label': 'SOH/Data Def', 'fixPoint': 0, 'valueColors': '0:W|1:C'} - self.assertDictEqual( - get_chan_plot_info('SOH/Data Def', {'samplerate': 10}, 'RT130'), - expected_result) + self.assertDictEqual(get_chan_plot_info('SOH/Data Def', 'RT130'), + expected_result) + + def test_get_chan_plot_info_masspos_channel(self): + with self.subTest("Mass position 'VM'"): + expected_result = {'channel': 'VM1', + 'plotType': 'linesMasspos', + 'height': 4, + 'unit': 'V', + 'linkedChan': None, + 'convertFactor': 0.1, + 'label': 'VM1-MassPos', + 'fixPoint': 1, + 'valueColors': None} + self.assertDictEqual(get_chan_plot_info('VM1', 'Q330'), + expected_result) + + with self.subTest("Mass position 'MassPos'"): + expected_result = {'channel': 'MassPos1', + 'plotType': 'linesMasspos', + 'height': 4, + 'unit': 'V', + 'linkedChan': None, + 'convertFactor': 1, + 'label': 'MassPos1', + 'fixPoint': 1, + 'valueColors': None} + self.assertDictEqual(get_chan_plot_info('MassPos1', 'RT130'), + expected_result) + + def test_get_chan_plot_info_seismic_channel(self): + with self.subTest("RT130 Seismic"): + expected_result = {'channel': 'DS2', + 'plotType': 'linesSRate', + 'height': 4, + 'unit': '', + 'linkedChan': None, + 'convertFactor': 1, + 'label': 'DS2', + 'fixPoint': 0, + 'valueColors': None} + self.assertDictEqual(get_chan_plot_info('DS2', 'RT130'), + expected_result) + + with self.subTest("MSeed Seismic"): + expected_result = {'channel': 'LHE', + 'plotType': 'linesSRate', + 'height': 4, + 'unit': '', + 'linkedChan': None, + 'convertFactor': 1, + 'label': 'LHE-EW', + 'fixPoint': 0, + 'valueColors': None} + self.assertDictEqual(get_chan_plot_info('LHE', 'Q330'), + expected_result) def test_get_chan_plot_info_data_type_is_unknown(self): """ @@ -44,10 +96,8 @@ class TestExtractData(unittest.TestCase): 'label': 'DEFAULT-Bad Channel ID', 'fixPoint': 0, 'valueColors': None} - self.assertDictEqual( - get_chan_plot_info('Bad Channel ID', - {'samplerate': 10}, 'Unknown'), - expected_result) + self.assertDictEqual(get_chan_plot_info('Bad Channel ID', 'Unknown'), + expected_result) # Channel exist in database expected_result = {'channel': 'LCE', @@ -59,12 +109,8 @@ class TestExtractData(unittest.TestCase): 'label': 'LCE-PhaseError', 'fixPoint': 0, 'valueColors': 'L:W|D:Y'} - self.assertDictEqual( - get_chan_plot_info('LCE', {'samplerate': 10}, 'Unknown'), - expected_result) - self.assertDictEqual( - get_chan_plot_info('LCE', {'samplerate': 10}, 'Unknown'), - expected_result) + self.assertDictEqual(get_chan_plot_info('LCE', 'Unknown'), + expected_result) def test_get_chan_plot_info_bad_channel_or_data_type(self): """ @@ -86,69 +132,54 @@ class TestExtractData(unittest.TestCase): # Data type has None value. None value comes from # controller.processing.detect_data_type. expected_result['label'] = 'DEFAULT-SOH/Data Def' - self.assertDictEqual( - get_chan_plot_info('SOH/Data Def', {'samplerate': 10}, None), - expected_result) + self.assertDictEqual(get_chan_plot_info('SOH/Data Def', None), + expected_result) # Channel and data type are empty strings expected_result['label'] = 'DEFAULT-' - self.assertDictEqual( - get_chan_plot_info('', {'samplerate': 10}, ''), - expected_result) + self.assertDictEqual(get_chan_plot_info('', ''), + expected_result) # Channel exists in database but data type does not expected_result['label'] = 'DEFAULT-SOH/Data Def' self.assertDictEqual( - get_chan_plot_info('SOH/Data Def', - {'samplerate': 10}, 'Bad Data Type'), + get_chan_plot_info('SOH/Data Def', 'Bad Data Type'), expected_result ) # Data type exists in database but channel does not expected_result['label'] = 'DEFAULT-Bad Channel ID' - self.assertDictEqual( - get_chan_plot_info('Bad Channel ID', - {'samplerate': 10}, 'RT130'), - expected_result) + self.assertDictEqual(get_chan_plot_info('Bad Channel ID', 'RT130'), + expected_result) # Both channel and data type exists in database but not their # combination expected_result['label'] = 'DEFAULT-SOH/Data Def' - self.assertDictEqual( - get_chan_plot_info('SOH/Data Def', {'samplerate': 10}, 'Q330'), - expected_result) - - def test_get_wf_plot_info(self): - """ - Test basic functionality of get_wf_plot_info - ensures returned - dictionary contains all the needed key. Bad channel IDs cases are - handled in tests for get_chan_label. - """ - result = get_wf_plot_info('CH1') - expected_keys = {'param', 'plotType', 'valueColors', 'height', - 'label', 'unit', 'channel', 'convertFactor'} - self.assertSetEqual(set(result.keys()), expected_keys) + self.assertDictEqual(get_chan_plot_info('SOH/Data Def', 'Q330'), + expected_result) - def test_get_chan_label_good_channel_id(self): + def test_get_seismic_chan_label_good_channel_id(self): """ - Test basic functionality of get_chan_label - channel ID ends in one - of the keys in conf.dbSettings.dbConf['seisLabel'] or starts with 'DS' + Test basic functionality of get_seismic_chan_label - channel ID ends + in one of the keys in conf.dbSettings.dbConf['seisLabel'] or + starts with 'DS' """ # Channel ID does not start with 'DS' - self.assertEqual(get_chan_label('CH1'), 'CH1-NS') - self.assertEqual(get_chan_label('CH2'), 'CH2-EW') - self.assertEqual(get_chan_label('CHG'), 'CHG') + self.assertEqual(get_seismic_chan_label('CH1'), 'CH1-NS') + self.assertEqual(get_seismic_chan_label('CH2'), 'CH2-EW') + self.assertEqual(get_seismic_chan_label('CHG'), 'CHG') # Channel ID starts with 'DS' - self.assertEqual(get_chan_label('DS-TEST-CHANNEL'), 'DS-TEST-CHANNEL') + self.assertEqual(get_seismic_chan_label('DS-TEST-CHANNEL'), + 'DS-TEST-CHANNEL') def test_get_chan_label_bad_channel_id(self): """ - Test basic functionality of get_chan_label - channel ID does not end in - one of the keys in conf.dbSettings.dbConf['seisLabel'] or is the empty - string. + Test basic functionality of get_seismic_chan_label - channel ID does + not end in one of the keys in conf.dbSettings.dbConf['seisLabel'] + or is the empty string. """ - self.assertRaises(IndexError, get_chan_label, '') + self.assertRaises(IndexError, get_seismic_chan_label, '') def test_get_signature_channels(self): """Test basic functionality of get_signature_channels""" -- GitLab