Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • software_public/passoft/sohstationviewer
1 result
Show changes
Commits on Source (4)
......@@ -86,3 +86,6 @@ ENV/
.idea/
.DS_Store
# program config
sohstationviewer/conf/read_settings.ini
......@@ -182,7 +182,9 @@ class MainWindow(QtWidgets.QMainWindow, UIMainWindow):
self.is_plotting_tps: bool = False
self.is_stopping: bool = False
self.background_black_radio_button.toggle()
self.read_config()
self.validate_config()
self.apply_config()
@QtCore.Slot()
def open_data_type(self) -> None:
......@@ -953,6 +955,45 @@ class MainWindow(QtWidgets.QMainWindow, UIMainWindow):
for window in QtWidgets.QApplication.topLevelWidgets():
window.close()
self.write_config()
def write_config(self):
"""
Write the current state of the program to the config file.
"""
self.config.set('FileRead', 'from_data_card',
str(self.from_data_card_check_box.isChecked()))
self.config.set('FileRead', 'data',
str(self.data_radio_button.isChecked()))
self.config.set('FileRead', 'sdata',
str(self.sdata_radio_button.isChecked()))
self.config.set('ColorMode', 'black',
str(self.background_black_radio_button.isChecked()))
self.config.set('ColorMode', 'white',
str(self.background_white_radio_button.isChecked()))
self.config.set('Gap', 'min_gap_length',
self.gap_len_line_edit.text())
self.config.set('Channels', 'mp123zne',
str(self.mass_pos_123zne_check_box.isChecked()))
self.config.set('Channels', 'mp456uvw',
str(self.mass_pos_456uvw_check_box.isChecked()))
self.config.set('Channels', 'all_waveform_chans',
str(self.all_wf_chans_check_box.isChecked()))
for i, checkbox in enumerate(self.ds_check_boxes, start=1):
self.config.set('Channels', f'ds{i}', str(checkbox.isChecked()))
self.config.set('Channels', 'mseed_wildcard',
self.mseed_wildcard_edit.text())
self.config.set('Channels', 'plot_tps',
str(self.tps_check_box.isChecked()))
self.config.set('Channels', 'plot_raw',
str(self.raw_check_box.isChecked()))
self.config.set('ChannelsPreference', 'all_soh',
str(self.all_soh_chans_check_box.isChecked()))
self.config.set('ChannelsPreference', 'pref_code',
self.curr_pref_soh_list_name_txtbox.text())
with open('sohstationviewer/conf/read_settings.ini', 'w') as file:
self.config.write(file)
def delete_old_temp_data_folder(self) -> None:
"""
Delete temp_data_folder which is used for keeping memmap files in case
......
......@@ -195,7 +195,7 @@ def get_gps_channel_prefix(data_obj: MSeed, data_type: str) -> Optional[str]:
def get_chan_soh_trace_as_dict(data_obj: MSeed, chan: str
) -> Dict[float, float]:
) -> Dict[float, List[float]]:
"""
Get the data of a channel as a dictionary mapping a data point's time to
its data. Suppose that gps data's spr <= 1.
......@@ -204,13 +204,12 @@ def get_chan_soh_trace_as_dict(data_obj: MSeed, chan: str
:return: a dict that maps the times of channel chan to its data
"""
chan_data = data_obj.soh_data[data_obj.selected_key][chan]
data = chan_data['tracesInfo']['data']
times = chan_data['tracesInfo']['times']
# Remove the filled in gaps from the data
data = data[~data.mask]
times = times[~times.mask]
data_dict = {time: data
for time, data in np.column_stack((times, data))}
traces = chan_data['tracesInfo']
times = np.hstack([trace['times'] for trace in traces])
data = np.hstack([trace['data'] for trace in traces])
data_dict = {}
for times_point, data_point in zip(times, data):
data_dict.setdefault(times_point, []).append(data_point)
return data_dict
......@@ -252,13 +251,15 @@ def extract_gps_data_pegasus_centaur(data_obj: MSeed, data_type: str
# There is no channel for GPS fix type in Pegasus and Centaur data,
# so we are giving it a dummy value.
fix_type = 'N/A'
lat = la_dict.get(time, None)
long = lo_dict.get(time, None)
height = el_dict.get(time, None)
current_lat = la_dict.get(time, None)
current_long = lo_dict.get(time, None)
current_height = el_dict.get(time, None)
# We are ignoring any point that does not have complete location data.
# It might be possible to ignore points with missing latitude or
# longitude, seeing as height is not required to plot a GPS point.
if lat is None or long is None or height is None:
if (current_lat is None or
current_long is None or
current_height is None):
continue
# Convert the location data to the appropriate unit. Centaur and
# Pegasus dataloggers both store latitude and longitude in microdegree,
......@@ -266,20 +267,26 @@ def extract_gps_data_pegasus_centaur(data_obj: MSeed, data_type: str
# stores elevation in micrometer while Pegasus stores it in centimeter,
# so we have to use a difference conversion factor for elevation
# depending on the data type.
lat = lat / 1e6
long = long / 1e6
# The GPS prefix is unique between Pegasus (V) and Centaur (G), so we
# can use it in place of the data type.
if gps_prefix == 'V':
height_factor = 100
else:
height_factor = 1e6
height = height / height_factor
height_unit = 'M'
formatted_time = UTCDateTime(time).strftime('%Y-%m-%d %H:%M:%S')
gps_point = GPSPoint(formatted_time, fix_type, num_sats_used, lat,
long, height, height_unit)
extracted_gps_points.append(gps_point)
for i, num_sats in enumerate(num_sats_used):
try:
lat = current_lat[i] / 1e6
long = current_long[i] / 1e6
# The GPS prefix is unique between Pegasus (V) and Centaur (G),
# so we can use it in place of the data type.
if gps_prefix == 'V':
height_factor = 100
else:
height_factor = 1e6
height = current_height[i] / height_factor
height_unit = 'M'
formatted_time = UTCDateTime(time).strftime(
'%Y-%m-%d %H:%M:%S'
)
gps_point = GPSPoint(formatted_time, fix_type, num_sats, lat,
long, height, height_unit)
extracted_gps_points.append(gps_point)
except IndexError:
break
# We only need to loop through one dictionary. If a time is not
# available for a channel, the GPS data point at that time would be
# invalid (it is missing a piece of data). Once we loop through a
......
......@@ -138,6 +138,10 @@ class SOHWidget(plotting_widget.PlottingWidget):
:param first_time: bool - flag identify when the data set is first
plotted, not zoom in yet
"""
# These channels contain GPS data, which we only show in the GPS
# dialog.
if chan_id in {'GLO', 'VLO', 'VLA', 'GLA', 'VEL', 'VNS', 'GNS', 'GEL'}:
return
chan_db_info = c_data['chan_db_info']
plot_type = chan_db_info['plotType']
if c_data['samplerate'] <= 1:
......
# UI and connectSignals for main_window
import configparser
from pathlib import Path
from typing import Union, List, Optional
from PySide2 import QtCore, QtGui, QtWidgets
......@@ -263,6 +265,8 @@ class UIMainWindow(object):
"""
self.doc_action: Union[QAction, None] = None
self.config: Union[configparser.ConfigParser, None] = None
def setup_ui(self, main_window):
"""
Setting up layout, widgets, menus for main_window
......@@ -451,6 +455,8 @@ class UIMainWindow(object):
gap_layout.addWidget(self.gap_len_line_edit)
gap_layout.addWidget(QLabel(' m'))
add_separation_line(left_layout)
mass_pos_layout = QHBoxLayout()
left_layout.addLayout(mass_pos_layout)
mass_pos_layout.addWidget(QLabel('Mass Pos '))
......@@ -785,3 +791,141 @@ class UIMainWindow(object):
self.read_button.clicked.connect(main_window.read_selected_files)
self.stop_button.clicked.connect(main_window.stop)
def read_config(self):
self.config = configparser.ConfigParser()
config_path = Path('sohstationviewer/conf/read_settings.ini')
if not config_path.exists():
default_config = '''
[FileRead]
from_data_card = False
data = False
sdata = False
[ColorMode]
black = True
white = False
[Gap]
min_gap_length =
[Channels]
mp123zne = False
mp456uvw = False
all_waveform_chans = False
ds1 = False
ds2 = False
ds3 = False
ds4 = False
ds5 = False
ds6 = False
ds7 = False
ds8 = False
mseed_wildcard =
plot_tps = False
plot_raw = False
[ChannelsPreference]
all_soh = True
pref_code =
'''
self.config.read_string(default_config)
else:
self.config.read(config_path)
def validate_config(self):
class BadConfigError(RuntimeError):
"""
Error raised when there is a problem with the configuration
"""
pass
expected_keys = {'from_data_card', 'data', 'sdata',
'black', 'white',
'min_gap_length',
'mp123zne', 'mp456uvw', 'all_waveform_chans', 'ds1',
'ds2', 'ds3', 'ds4', 'ds5', 'ds6', 'ds7', 'ds8',
# noqa
'mseed_wildcard', 'plot_tps', 'plot_raw',
'all_soh', 'pref_code'}
loaded_keys = {item[0]
for (section, _) in self.config.items()
for item in self.config.items(section)}
missing_keys = expected_keys - loaded_keys
if missing_keys:
raise BadConfigError(f'Some required keys are missing. Please'
f'make sure they are in the config file. The '
f'missing keys are: {", ".join(missing_keys)}'
)
data_checked = self.config.getboolean('FileRead', 'data')
sdata_checked = self.config.getboolean('FileRead', 'sdata')
if data_checked and sdata_checked:
raise BadConfigError('data and sdata cannot both be chosen.')
black_color_mode = self.config.getboolean('ColorMode', 'black')
white_color_mode = self.config.getboolean('ColorMode', 'white')
if black_color_mode and white_color_mode:
raise BadConfigError('Cannot be in both color modes at once.')
all_waveform_chans = self.config.getboolean('Channels',
'all_waveform_chans')
data_stream_chosen = any(self.config.getboolean('Channels', f'ds{i}')
for i in range(1, 9)
)
mseed_wildcard = self.config.get('Channels',
'mseed_wildcard')
wildcard_not_empty = (mseed_wildcard != '')
if all_waveform_chans and (data_stream_chosen or wildcard_not_empty):
raise BadConfigError(
'Waveform channel selector can only be in one mode at a time.')
all_soh = self.config.getboolean('ChannelsPreference', 'all_soh')
channel_pref_code = self.config.get('ChannelsPreference', 'pref_code')
if all_soh and (channel_pref_code != ''):
raise BadConfigError('You can only choose one list of channels to '
'be plotted.')
def apply_config(self):
get_bool = self.config.getboolean
self.from_data_card_check_box.setChecked(
get_bool('FileRead', 'from_data_card')
)
self.data_radio_button.setChecked(get_bool('FileRead', 'data'))
self.sdata_radio_button.setChecked(get_bool('FileRead', 'sdata'))
self.background_black_radio_button.setChecked(
get_bool('ColorMode', 'black')
)
self.background_white_radio_button.setChecked(
get_bool('ColorMode', 'white')
)
self.gap_len_line_edit.setText(
self.config.get('Gap', 'min_gap_length')
)
self.mass_pos_123zne_check_box.setChecked(
get_bool('Channels', 'mp123zne')
)
self.mass_pos_456uvw_check_box.setChecked(
get_bool('Channels', 'mp456uvw')
)
self.all_wf_chans_check_box.setChecked(
get_bool('Channels', 'all_waveform_chans')
)
for i, checkbox in enumerate(self.ds_check_boxes, start=1):
checkbox.setChecked(get_bool('Channels', f'ds{i}'))
self.mseed_wildcard_edit.setText(
self.config.get('Channels', 'mseed_wildcard')
)
self.tps_check_box.setChecked(get_bool('Channels', 'plot_tps'))
self.raw_check_box.setChecked(get_bool('Channels', 'plot_raw'))
self.all_soh_chans_check_box.setChecked(
get_bool('ChannelsPreference', 'all_soh')
)
self.curr_pref_soh_list_name_txtbox.setText(
self.config.get('ChannelsPreference', 'pref_code')
)