Repository navigation
Expand file tree
/
Copy pathmain.py
More file actions
276 lines (233 loc) · 11.3 KB
/
Copy pathmain.py
File metadata and controls
276 lines (233 loc) · 11.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
import sys
import logging
import traceback
from fbs_runtime.application_context import ApplicationContext, cached_property
from matplotlib.backends.qt_compat import QtCore, QtWidgets, QtGui, is_pyqt5
from my_widgets import *
if is_pyqt5():
pass
else:
pass
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtWidgets.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtWidgets.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtWidgets.QApplication.translate(context, text, disambig)
class AppContext(ApplicationContext):
if sys.platform == 'win32':
from pathlib import Path
home = str(Path.home())
logging.basicConfig(filename=home+'\qcsoft.log')
else:
logging.basicConfig(filename='/tmp/qcsoft.log')
def run(self):
version = self.build_settings["version"]
name = self.build_settings["app_name"]
self.window.setWindowTitle(name + " v" + str(version))
self.window.show()
return self.app.exec_()
def exception_hook(self, exc_type, exc_value, exc_traceback):
self.window.critical_dialog(title="ERROR!", text="Uncaught exception", info_text="log file saved at '/tmp/qcsoft.log'", details=traceback.format_tb(exc_traceback))
logging.error(
{"Uncaught exception, filename", self.window.file_name[0][0]},
exc_info=(exc_type, exc_value, exc_traceback)
)
@cached_property
def window(self):
return ApplicationWindow()
class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
super(ApplicationWindow, self).__init__()
# self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
self._main = QtWidgets.QStackedWidget()
self.file_name = "NO NAME"
# self._main = QtWidgets.QWidget()
self.setCentralWidget(self._main)
# self.setWindowTitle("UHSLC QC Software")
self.setWindowIcon(QtGui.QIcon('uhslclogotext72_pfL_icon.ico'))
self.resize(1837, 1200)
# Create Screen objects
self.start_screen = Start(self)
self.second_screen = HelpScreen(self)
self._main.addWidget(self.start_screen)
self._main.addWidget(self.second_screen)
self._main.setCurrentWidget(self.start_screen)
self.start_screen.clicked.connect(lambda: self._main.setCurrentWidget(self.second_screen))
self.second_screen.clicked.connect(lambda: self._main.setCurrentWidget(self.start_screen))
self.setStatusTip("Permanent status bar")
# Create an action in the menu bar that is later on assigned to one of
# the options (e.g. File, Edit, View etc) in the menu bar
close_app = QtWidgets.QAction("&Exit", self)
close_app.setShortcut("Ctrl+Q")
# Show the tip in the status bar on hover
close_app.setStatusTip('Leave the app')
close_app.triggered.connect(self.close_application)
open_help_menu = QtWidgets.QAction("&Instructions", self)
open_help_menu.setShortcut("F1")
open_help_menu.triggered.connect(self.start_screen.clicked.emit)
# open_help_menu.triggered.connect(self.open_help_menu)
open_file = QtWidgets.QAction("&Open monp", self)
open_file.setShortcut("Ctrl+O")
open_file.setStatusTip('Load a File')
open_file.triggered.connect(self.file_open)
reload_file = QtWidgets.QAction("&Reload", self)
reload_file.setShortcut("Ctrl+R")
reload_file.setStatusTip('Reload all file(s) that were loaded')
reload_file.triggered.connect(self.get_loaded_files)
opents_file = QtWidgets.QAction("&Open ts", self)
opents_file.setShortcut("Ctrl+T")
opents_file.setStatusTip('Opens ts folder')
opents_file.triggered.connect(self.open_ts)
self.statusBar()
# Create dropwon menu
main_menu = self.menuBar()
# Add options to the menuBar
file_menu = main_menu.addMenu('&File')
help_menu = main_menu.addMenu('&Help')
# Connect action with the option
file_menu.addAction(open_file)
file_menu.addAction(reload_file)
file_menu.addAction(opents_file)
file_menu.addAction(close_app)
help_menu.addAction(open_help_menu)
def file_open(self, reload = False, ts = False):
if not reload:
# filters = "s*.dat;; ts*.dat"
if ts:
filters = "t*.dat"
else:
filters = "s*.dat"
if ts:
if st.get_path(st.SAVE_KEY):
path = st.get_path(st.SAVE_KEY)
else:
# path = "C:\\Users\\komar\\OneDrive\\Desktop\\monp"
path = os.path.expanduser('~')
else:
if st.get_path(st.LOAD_KEY):
path = st.get_path(st.LOAD_KEY)
else:
# path = "C:\\Users\\komar\\OneDrive\\Desktop\\monp"
path = os.path.expanduser('~')
self.file_name = QtWidgets.QFileDialog.getOpenFileNames(self, 'Open File', path, filters)
# file_name = QtWidgets.QFileDialog.getOpenFileNames(self, 'Open File', filter)
# Validating files selected
if self.is_valid_files(self.file_name):
pass
else:
self.critical_dialog(title="ERROR",
text="Warning, wrong files selected",
info_text="The files need to belong to the adjacent months and the same station. Please select valid files to continue",
details=''''MAC:
The files are loaded in order in which they were selected. Select files from the oldest to the youngest.\nWINDOWS:
The order is determined by the file order in the File Explorer. The files should be sorted by name before selecting them.
''')
return
try:
# in_file = open(name[0],'r')
self.month_count = len(self.file_name[0])
print('FILENAME', self.file_name[0][0])
self.start_screen.sens_objects = {} # Collection of Sensor objects for station for one month
comb_data = np.ndarray(
0) # ndarray of concatonated data for all the months that were loaded for a particular station
comb_time_col = [] # combined rows of all time columns for all the months that were loaded for a
# particular station
de = [] # List od DataExtractor objects for each month loaded which hold all the necessary data
line_count = [] # array for the number of lines (excluding headers and 9999s)for each month that were
# loaded for a particular station. Added as an attribute to respective sensor objects
self.start_screen.lineEdit2.setText("Loaded: " + str(self.month_count) + " months")
# Create DataExtractor for each month that was loaded into program
for j in range(self.month_count):
de.append(DataExtractor(self.file_name[0][j]))
# The reason de[0] is used is because the program only allows to load
# multiple months for the same station, so the station name will be the same
station_name = de[0].headers[0][:6]
my_station = Station(station_name, [0, 1])
comb_headers = []
# Cycle through all the Sensors
# The reason de[0] is used is because the program only allows to load
# multiple months for the same station, so the station sensors should be the same
# But what if a sensor is ever added to a station??? Check with fee it this ever happens
for i in range(len(de[0].sensor_ids)):
# cycle through all the months loaded (ie. DataExtractor objects)
for d in de:
comb_data = np.append(comb_data, d.data_all[de[0].sensor_ids[i][-3:]])
comb_time_col = comb_time_col + d.infos_time_col[de[0].sensor_ids[i][-3:]]
line_count.append(len(d.infos_time_col[de[0].sensor_ids[i][-3:]]))
comb_headers.append(d.headers[i])
self.start_screen.sens_objects[de[0].sensor_ids[i][-3:]] = Sensor(my_station, de[0].frequencies[i],
de[-1].refs[i], de[0].sensor_ids[i],
de[0].init_dates[i], comb_data,
comb_time_col, comb_headers)
self.start_screen.sens_objects[
de[0].sensor_ids[i][-3:]].line_num = line_count # adding a line_num attribute for each sensor
# Empty the combined data
comb_time_col = []
comb_data = np.ndarray(0)
line_count = []
comb_headers = []
self.start_screen.make_sensor_buttons(self.start_screen.sens_objects)
except (FileNotFoundError, IndexError) as e:
print('Error:', e)
def critical_dialog(self, title, text, info_text, details):
msg_box = QtWidgets.QMessageBox(self)
msg_box.setIcon(QtWidgets.QMessageBox.Critical)
msg_box.setWindowTitle(title)
msg_box.setText(text)
msg_box.setInformativeText(info_text)
msg_box.setDetailedText(str(details))
msg_box.setDefaultButton(QtWidgets.QMessageBox.Ok)
msg_box.exec_()
def pairwise_diff(self, lst):
diff = 0
result = []
for i in range(len(lst) - 1):
# subtracting the alternate numbers
diff = lst[i] - lst[i + 1]
result.append(diff)
return result
def is_valid_files(self, files):
dates = []
names = []
result = []
# extract dates and station 4 letter codes for every file that was loaded
for file in files[0]:
if file[-8:-4].isdigit():
dates.append(int(file[-8:-4]))
# check if monp file or a TS file
if file.split("/")[-1][0] == "s":
names.append(file.split("/")[-1][1:5])
else:
names.append(file.split("/")[-1][0:4])
# check the difference between all dates
for val in self.pairwise_diff(dates):
if val != -1 and val != -89:
result.append(val)
# check if the files selected are all from the same station
if names[1:] != names[:-1]:
return False
return len(result) == 0
def close_application(self):
choice = QtWidgets.QMessageBox.question(self, 'Warning', "Are you sure you want to quit?",
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
if choice == QtWidgets.QMessageBox.Yes:
sys.exit()
else:
pass
def get_loaded_files(self):
self.file_open(reload=True)
def open_ts(self):
self.file_open(reload=False, ts = True)
# return self.file_name;
if __name__ == '__main__':
appctxt = AppContext()
sys.excepthook = appctxt.exception_hook
exit_code = appctxt.run()
sys.exit(exit_code)