diff --git a/OpenOTDR.py b/OpenOTDR.py
index 0b0cb4d..0c7b9b4 100755
--- a/OpenOTDR.py
+++ b/OpenOTDR.py
@@ -5,19 +5,26 @@
import json
from collections import deque
from threading import Lock
-from PyQt5 import QtWidgets
-from PyQt5 import QtPrintSupport
-from PyQt5 import QtGui
-from PyQt5 import QtCore
+from PyQt6 import QtWidgets
+from PyQt6.QtWidgets import QFileDialog
+from PyQt6 import QtPrintSupport
+from PyQt6 import QtGui
+from PyQt6 import QtCore
+#from PyQt6 import Qt
+import PyQt6
+import PyQt6.QtCore
import numpy as np
from scipy.ndimage import zoom
from scipy.signal import find_peaks
-from pyotdr import sorparse
+#from pyotdr import sorparse
+import otdrparser
from matplotlib.figure import Figure
from matplotlib import cm
from matplotlib import colors
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
+from matplotlib.widgets import Cursor
+
import mainwindow
@@ -44,28 +51,50 @@ def _low_pass_filter_trace(a_raw_trace, window_len):
return a_trace
-def prepare_data(d_data, window_len):
+def prepare_data(self, window_len):
'''Transforms the trace data to unify sample width and signal quality'''
- a_raw_trace = d_data["trace"]
+ #a_raw_trace = d_data["trace"]
# Smoothing
- a_smooth_trace = _low_pass_filter_trace(a_raw_trace, window_len)
+ #a_smooth_trace = _low_pass_filter_trace(a_raw_trace, window_len)
# Scale to ensure resolution per distance unit is equal.
- a_trace = zoom(a_smooth_trace, zoom=(1.0, d_data["meta"]["FxdParams"]["resolution"]), order=1)
- # Offsetting to make all launch levels the same
-# print("a_trace[0] =", a_trace[0])
-# print("len(a_trace[0]) =", len(a_trace[0]))
- try:
- n_offset = -a_trace[0][325]
- except:
- n_offset = 0.0
-# print("n_offset=", n_offset)
- a_trace[0] = a_trace[0] + n_offset
- return {"meta": d_data["meta"], "trace": a_trace}
+ #a_trace = zoom(a_smooth_trace, zoom=(1.0, d_data["meta"]["FxdParams"]["resolution"]), order=1)
+ self.meta_model.clear()
+ self.meta_model.setHorizontalHeaderLabels(['Name', 'Value'])
+
+ raw_data = {}
+ raw_data[0] = []
+ raw_data[1] = []
+ for kind in self.d_meta:
+ if kind.get('name', None) == 'DataPts':
+ data_pts = kind.get('data_points', None)
+ for dp in data_pts:
+ raw_data[0].append(dp[0])
+ raw_data[1].append(dp[1])
+
+ if kind.get('name', None) in ('GenParams', 'SupParams', 'FxdParams'):
+# print(kind)
+ for k in kind:
+# print("k=", k)
+ if k == 'name':
+ continue
+ current_row = self.meta_model.rowCount()
+ self.meta_model.insertRow(current_row)
+ value_text = QtGui.QStandardItem()
+ value_text.setText(str(k))
+ value_text.setEditable(False)
+ self.meta_model.setItem(current_row, 0, value_text)
+#
+ value_text = QtGui.QStandardItem()
+ value_text.setText(str(kind.get(k, None)))
+ value_text.setEditable(False)
+ self.meta_model.setItem(current_row, 1, value_text)
+
+ return raw_data
def differentiate_data(d_data):
'''Calculates the 1st order differential of the data'''
- a_raw_trace = d_data["trace"]
+ a_raw_trace = d_data
a_diff_trace = np.diff(a_raw_trace[0])
a_clean_trace = []
for sample_index in range(len(a_raw_trace[0])):
@@ -133,9 +162,18 @@ def __init__(self):
#
self.events_proxy_model = NaturalSortFilterProxyModel()
self.events_proxy_model.setSourceModel(self.events_model)
- self.events_proxy_model.sort(1, QtCore.Qt.AscendingOrder)
- #
+# self.events_proxy_model.sort(1, PyQt6.QtCore.Qt.SortOrder.AscendingOrder)
self.user_interface.eventTableView.setModel(self.events_proxy_model)
+ self.user_interface.eventTableView.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeMode.ResizeToContents)
+#
+ # meta processing model
+ self.meta_model = QtGui.QStandardItemModel()
+#
+ self.meta_proxy_model = NaturalSortFilterProxyModel()
+ self.meta_proxy_model.setSourceModel(self.meta_model)
+# self.meta_proxy_model.sort(1, PyQt6.QtCore.Qt.SortOrder.AscendingOrder)
+ self.user_interface.metaTableView.setModel(self.meta_proxy_model)
+ self.user_interface.metaTableView.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeMode.ResizeToContents)
#
self.user_interface.openProject.clicked.connect(self.open_project)
self.user_interface.saveProject.clicked.connect(self.save_project)
@@ -146,6 +184,9 @@ def __init__(self):
self.user_interface.recalculateEvents.clicked.connect(self.recalculate_events)
self.window_len = 0
self.canvas = None
+ self.d_meta = None
+ self.plt = None
+ self.cursor = None
self.toolbar = None
self.raw_features = []
self.raw_traces = []
@@ -175,34 +216,89 @@ def __preprocess_data(self, d_meta, l_raw_trace):
def _load_file(self, url, _project=False):
'''Load the raw SOR file from provided url into the internal data format'''
- if not _project:
- _, d_meta, l_raw_trace = sorparse(url)
- d_meta["url"] = url
- else:
- d_meta = _project["meta"]
- l_raw_trace = _project["raw_trace"]
- self.files[url] = {"meta": d_meta, "raw_trace": l_raw_trace}
+ with open(url, 'rb') as fp:
+ d_meta = otdrparser.parse(fp)
+ self.d_meta = d_meta
+ data_pts = None
+ for row in d_meta:
+ if row.get('name', None) == "DataPts":
+ data_pts = row
+ self.files[url] = {"meta": d_meta, "raw_trace": data_pts}
# print("d_meta=", json.dumps(d_meta, sort_keys=True, indent=4))
# print("l_raw_trace=", json.dumps(l_raw_trace, sort_keys=True, indent=4))
- a_trace = self.__preprocess_data(d_meta, l_raw_trace)
- d_data= prepare_data({"meta":d_meta, "trace":a_trace}, self.window_len)
+# a_trace = self.__preprocess_data(d_meta, l_raw_trace)
+ d_data= prepare_data(self, self.window_len)
filename = os.path.basename(url)
item = QtGui.QStandardItem(filename)
item.data = d_data
self.project_model.appendRow(item)
+ def hover(event, graph_info):
+# print("hover event:", dir(event))
+# hover graph_info: ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_guiEvent', '_guiEvent_deleted', '_last_axes_ref', '_lastevent', '_process', '_set_inaxes', 'button', 'canvas', 'dblclick', 'guiEvent', 'inaxes', 'key', 'lastevent', 'modifiers', 'name', 'step', 'x', 'xdata', 'y', 'ydata']
+
+ print("hover graph_info:", dir(graph_info))
+ print("graph_info.guiEvent:", graph_info.guiEvent)
+ print("graph_info.inaxes:", graph_info.inaxes)
+ print("graph_info.key:", graph_info.key)
+ print("graph_info.x:", graph_info.x)
+ print("graph_info.y:", graph_info.y)
+ print("graph_info.xdata(km):", graph_info.xdata)
+ print("grpah_info.xdata(feet):", graph_info.xdata * 3280.8399)
+ print("graph_info.ydata:", graph_info.ydata)
+ print("graph_info.name:", graph_info.name)
+
+ if graph_info.inaxes == graph_info.ax:
+ cont, ind = line.contains(event)
+ if cont:
+ update_annot(ind)
+ annot.set_visible(True)
+ fig.canvas.draw_idle()
+ else:
+ if vis:
+ annot.set_visible(False)
+ fig.canvas.draw_idle()
+
+
+ def on_draw(self, event):
+ print("on_draw:", event)
+# self.cursor = Cursor(self.plt, horizOn=True, vertOn=True, useblit=True, color='red', linewidth=2)
+
+ def button_press(event, graph_info):
+# print("button_press event:", dir(event))
+# button_press graph_info: ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_guiEvent', '_guiEvent_deleted', '_last_axes_ref', '_lastevent', '_process', '_set_inaxes', 'button', 'canvas', 'dblclick', 'guiEvent', 'inaxes', 'key', 'lastevent', 'modifiers', 'name', 'step', 'x', 'xdata', 'y', 'ydata']
+
+# print("button_press graph_info:", dir(graph_info))
+ print("graph_info.guiEvent:", graph_info.guiEvent)
+ print("graph_info.inaxes:", graph_info.inaxes)
+ print("graph_info.key:", graph_info.key)
+ print("graph_info.button:", graph_info.button) # (1 left, 2 middle, 3 right)
+ print("graph_info.dblclick:", graph_info.dblclick) # doubleclick?
+# print("graph_info.x:", graph_info.x)
+# print("graph_info.y:", graph_info.y)
+ print("graph_info.xdata(km):", graph_info.xdata)
+ print("grpah_info.xdata(feet):", graph_info.xdata * 3280.8399)
+
+ print("graph_info.ydata:", graph_info.ydata)
+ print("graph_info.name:", graph_info.name)
+
+
def _draw(self):
'''(re)draw the plot with the latest data'''
fig = Figure()
- plt = fig.add_subplot(1, 1, 1)
+ self.plt = fig.add_subplot(1, 1, 1)
if self.raw_traces:
+# print("self.raw_traces:", self.raw_traces)
for d_final_data in self.raw_traces:
- wavelength = d_final_data["meta"]["GenParams"]["wavelength"]
+ wavelength = 1310
+ print("d_final_data", d_final_data)
# print("wavelength=", wavelength)
- plt.plot(d_final_data["trace"][1],
- d_final_data["trace"][0],
+ self.plt.plot(d_final_data[0],
+ d_final_data[1],
label=wavelength,
- color=wavelength_to_rgb(wavelength))
+ color=wavelength_to_rgb(str(wavelength)))
+# self.plt.set_xlim([0, None])
+
if self.canvas:
self.user_interface.graphLayout.removeWidget(self.canvas)
self.canvas.close()
@@ -210,19 +306,29 @@ def _draw(self):
self.user_interface.graphLayout.removeWidget(self.toolbar)
self.toolbar.close()
fig.legend()
+# if i want to have my own hover function
+# fig.canvas.mpl_connect("motion_notify_event", self.hover)
+ fig.canvas.mpl_connect("button_press_event", self.button_press)
+# fig.canvas.mpl_connect("scroll_event", self.zoom)
+ fig.canvas.mpl_connect('draw_event', self.on_draw)
+
self.canvas = FigureCanvas(fig)
- self.toolbar = CustomNavigationToolbar(self.canvas, self, coordinates=True)
+# self.toolbar = CustomNavigationToolbar(self.canvas, self, coordinates=True)
+ self.toolbar = NavigationToolbar(self.canvas, self, coordinates=True)
+ self.cursor = Cursor(self.plt, horizOn=True, vertOn=True, useblit=True, color='red', linewidth=2)
self.user_interface.graphLayout.addWidget(self.canvas)
self.user_interface.graphLayout.addWidget(self.toolbar)
+ self.recalculate_events()
+
def open_project(self):
'''Load a project from a file'''
if self.busy.locked():
return
with self.busy:
- options = QtWidgets.QFileDialog.Options()
- options |= QtWidgets.QFileDialog.DontUseNativeDialog
- uri, _ = QtWidgets.QFileDialog.getOpenFileName(self, "Open project", "", "OpenOTDR Project Files(*.opro);;All Files (*)", options=options)
+ dialog = QtWidgets.QFileDialog(self)
+ dialog.setOption(QFileDialog.Option.DontUseNativeDialog, True)
+ uri, _ = dialog.getOpenFileName(self, "Open project", "", "OpenOTDR Project Files(*.opro);;All Files (*)")
if uri:
with open(uri, "r") as file:
content = json.load(file)
@@ -236,15 +342,16 @@ def open_project(self):
self._draw()
self._draw()
self.recalculate_events()
+ self._draw
def save_project(self):
'''Save a project to a file'''
if self.busy.locked():
return
with self.busy:
- options = QtWidgets.QFileDialog.Options()
- options |= QtWidgets.QFileDialog.DontUseNativeDialog
- uri, _ = QtWidgets.QFileDialog.getSaveFileName(self, "Save project", "", "OpenOTDR Project Files(*.opro);;All Files (*)", options=options)
+ dialog = QtWidgets.QFileDialog(self)
+ dialog.setOption(QFileDialog.Option.DontUseNativeDialog, True)
+ uri, _ = dialog.getSaveFileName(self, "Save project", "", "OpenOTDR Project Files(*.opro);;All Files (*)")
if uri:
_, extension = os.path.splitext(uri)
if not extension:
@@ -274,16 +381,28 @@ def add_trace(self):
if self.busy.locked():
return
with self.busy:
- options = QtWidgets.QFileDialog.Options()
- options |= QtWidgets.QFileDialog.DontUseNativeDialog
- files, _ = QtWidgets.QFileDialog.getOpenFileNames(self, "Add traces", "", "OTDR Trace Files(*.sor);;All Files (*)", options=options)
+ dialog = QtWidgets.QFileDialog(self)
+ dialog.setOption(QFileDialog.Option.DontUseNativeDialog, True)
+ files, _ = dialog.getOpenFileNames(self, "Add traces", "", "OTDR Trace Files(*.sor);;All Files (*)")
if not files:
return
for filename in files:
self._load_file(filename)
+ l_traces = []
+ l_feature_points = []
for index in range(self.project_model.rowCount()):
raw_data = self.project_model.item(index).data
self.raw_traces.append(raw_data)
+ d_data = prepare_data(self, self.window_len)
+ l_traces.append(d_data)
+ l_feature_points.append(find_edges(differentiate_data(d_data)))
+ raw_features = l_feature_points
+ raw_traces = l_traces
+# print("add_trace: raw_features:", raw_features)
+# if not raw_features:
+# return
+ d_events = self._filter_events(raw_features)
+ self._update_events_table(d_events, raw_traces)
self._draw()
def remove_trace(self):
@@ -298,14 +417,14 @@ def remove_trace(self):
self.project_model.removeRow(index.row())
del self.raw_traces[index.row()]
self._draw()
-
+
@staticmethod
def _filter_events(raw_features):
'''Filter the detected features of each trace to make a single set with no duplicates or ghosts'''
d_events = {}
for trace_features in raw_features:
for index, feature in enumerate(trace_features[2]):
- feature_position = round_sig(feature, 1)
+ feature_position = round_sig(feature, 3)
if feature_position not in d_events and feature_position-0.1 not in d_events and feature_position+0.1 not in d_events:
d_events[feature_position] = {
"indexes": []
@@ -344,51 +463,125 @@ def __calculate_loss_and_dispersion(self, raw_traces, meta_data):
def _update_events_table(self, d_events, raw_traces):
'''Update the events table in the UI'''
+ print("_update_events_table")
self.events_model.clear()
- self.events_model.setHorizontalHeaderLabels(['Event',
- 'Distance (km)',
- 'Loss (dB)',
- 'Dispersion factor'])
- #
- for position, meta_data in d_events.items():
- current_row = self.events_model.rowCount()
- self.events_model.insertRow(current_row)
- event_position = QtGui.QStandardItem()
- event_position.setText(str(position))
- event_position.setEditable(False)
- self.events_model.setItem(current_row, 1, event_position)
- loss, dispersion_factor = self.__calculate_loss_and_dispersion(raw_traces, meta_data)
- event_loss = QtGui.QStandardItem()
- event_loss.setText(str(loss))
- event_loss.setEditable(False)
- self.events_model.setItem(current_row, 2, event_loss)
- event_dispersion = QtGui.QStandardItem()
- event_dispersion.setText(str(dispersion_factor))
- event_dispersion.setEditable(False)
- self.events_model.setItem(current_row, 3, event_dispersion)
- event_type = QtGui.QStandardItem()
- event_type.setEditable(True)
- self.events_model.setItem(current_row, 0, event_type)
+ key_events = None
+ for row in self.d_meta:
+ if row.get('name', None) == 'KeyEvents':
+ key_events = row
+# print("update_events_table: key_events:", key_events)
+ num_events = 0
+ self.events_model.setHorizontalHeaderLabels(['comment', 'dist(km)', 'dist(ft)', 'peak', 'refl loss', 'slope', 'splice_loss', 'type'])
+ if key_events is not None:
+ number_of_events = int(key_events.get('number_of_events', 0))
+ print("number_of_events:", number_of_events)
+
+ for event in key_events.get('events', []):
+ current_row = self.events_model.rowCount()
+ self.events_model.insertRow(current_row)
+
+ event_comment = QtGui.QStandardItem()
+ event_comment.setText(str(event.get('comment')))
+ event_comment.setEditable(False)
+ self.events_model.setItem(current_row, 0, event_comment)
+
+ event_position_km = QtGui.QStandardItem()
+ event_position_km.setText(str(event.get('distance_of_travel', 0)))
+ event_position_km.setEditable(False)
+ self.events_model.setItem(current_row, 1, event_position_km)
+
+ event_position_ft = QtGui.QStandardItem()
+ event_position_ft.setEditable(False)
+ event_position_ft.setText(str(float(event.get('distance_of_travel', 0)) * 3280.8399))
+ self.events_model.setItem(current_row, 2, event_position_ft)
+
+ event_peak = QtGui.QStandardItem()
+ event_peak.setText(str(event.get('peak_point')))
+ event_peak.setEditable(False)
+ self.events_model.setItem(current_row, 3, event_peak)
+
+ event_loss = QtGui.QStandardItem()
+ event_loss.setText(str(event.get('reflection_loss')))
+ event_loss.setEditable(False)
+ self.events_model.setItem(current_row, 4, event_loss)
+
+ event_slope = QtGui.QStandardItem()
+ event_slope.setText(str(event.get('slope')))
+ event_slope.setEditable(False)
+ self.events_model.setItem(current_row, 5, event_slope)
+
+ event_splice_loss = QtGui.QStandardItem()
+ event_splice_loss.setText(str(event.get('splice_loss')))
+ event_splice_loss.setEditable(False)
+ self.events_model.setItem(current_row, 6, event_splice_loss)
+
+ event_type = QtGui.QStandardItem()
+ event_type.setText(str(event.get('event_type_details')['event']))
+ event_type.setEditable(False)
+ self.events_model.setItem(current_row, 7, event_type)
+
+## self.events_model.setHorizontalHeaderLabels(['Event',
+## 'Dist (km)',
+## 'Loss (dB)',
+## 'Dispersion factor', 'Dist ft'])
+###
+##
+## #
+## for position, meta_data in d_events.items():
+## current_row = self.events_model.rowCount()
+## self.events_model.insertRow(current_row)
+## event_position_km = QtGui.QStandardItem()
+## event_position_km.setText(str(position))
+## event_position_km.setEditable(False)
+## self.events_model.setItem(current_row, 1, event_position_km)
+##
+## event_position_ft = QtGui.QStandardItem()
+## event_position_ft.setEditable(False)
+## event_position_ft.setText(str(position * 3280.8399))
+## self.events_model.setItem(current_row, 4, event_position_ft)
+##
+## loss, dispersion_factor = self.__calculate_loss_and_dispersion(raw_traces, meta_data)
+##
+## event_loss = QtGui.QStandardItem()
+## event_loss.setText(str(loss))
+## event_loss.setEditable(False)
+## self.events_model.setItem(current_row, 2, event_loss)
+##
+## event_dispersion = QtGui.QStandardItem()
+## event_dispersion.setText(str(dispersion_factor))
+## event_dispersion.setEditable(False)
+## self.events_model.setItem(current_row, 3, event_dispersion)
+##
+## # pull in event type from the trace ideally
+## event_type = QtGui.QStandardItem()
+## event_type.setEditable(True)
+## self.events_model.setItem(current_row, 0, event_type)
+##
self.events_model.sort(1)
+ self.user_interface.eventTableView.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeMode.ResizeToContents)
+
def recalculate_events(self):
'''Recalculate the events'''
+ print("starting recalculate_events()")
if self.busy.locked():
+ print("recalculate_events self.busy.locked()")
return
with self.busy:
l_traces = []
l_feature_points = []
for index in range(self.project_model.rowCount()):
raw_data = self.project_model.item(index).data
- d_data = prepare_data(raw_data, self.window_len)
+ d_data = prepare_data(self, self.window_len)
l_traces.append(d_data)
l_feature_points.append(find_edges(differentiate_data(d_data)))
raw_features = l_feature_points
raw_traces = l_traces
+ print("recalculate_events: raw_features:", raw_features)
if not raw_features:
return
d_events = self._filter_events(raw_features)
- self._update_events_table(d_events, raw_traces)
+ self._update_events_table(d_events, d_data)
APP = QtWidgets.QApplication(sys.argv)
@@ -397,4 +590,4 @@ def recalculate_events(self):
MAIN_WINDOW.setWindowTitle("OpenOTDR")
MAIN_WINDOW.show()
-sys.exit(APP.exec_())
+sys.exit(APP.exec())
diff --git a/README.md b/README.md
index 7068a03..6786974 100644
--- a/README.md
+++ b/README.md
@@ -4,5 +4,5 @@ OpenOTDR is an Open Source OTDR reporting tool.
It takes raw OTDR traces as .SOR files, detects and classifies features on the trace, and generates reports.
-You may need `pyqt5-dev-tools` package if you edit the ui file
-then you will need to run `pyuic5 -x mainwindow.ui -o mainwindow.py`
+You may need `pyqt6-dev-tools` package if you edit the ui file
+then you will need to run `pyuic6 -x mainwindow.ui -o mainwindow.py`
diff --git a/mainwindow.py b/mainwindow.py
index e05a389..c375325 100644
--- a/mainwindow.py
+++ b/mainwindow.py
@@ -1,97 +1,94 @@
-# -*- coding: utf-8 -*-
-
# Form implementation generated from reading ui file 'mainwindow.ui'
#
-# Created by: PyQt5 UI code generator 5.15.9
+# Created by: PyQt6 UI code generator 6.7.1
#
-# WARNING: Any manual changes made to this file will be lost when pyuic5 is
+# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again. Do not edit this file unless you know what you are doing.
-from PyQt5 import QtCore, QtGui, QtWidgets
+from PyQt6 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
- MainWindow.resize(1280, 755)
- self.mainWidget = QtWidgets.QWidget(MainWindow)
+ MainWindow.resize(1280, 760)
+ self.mainWidget = QtWidgets.QWidget(parent=MainWindow)
self.mainWidget.setObjectName("mainWidget")
self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.mainWidget)
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
- self.tabWidget = QtWidgets.QTabWidget(self.mainWidget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
+ self.tabWidget = QtWidgets.QTabWidget(parent=self.mainWidget)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding)
+ sizePolicy.setHorizontalStretch(1)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth())
self.tabWidget.setSizePolicy(sizePolicy)
self.tabWidget.setMinimumSize(QtCore.QSize(320, 720))
- self.tabWidget.setTabPosition(QtWidgets.QTabWidget.West)
self.tabWidget.setObjectName("tabWidget")
self.projectWidget = QtWidgets.QWidget()
self.projectWidget.setObjectName("projectWidget")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.projectWidget)
self.verticalLayout_3.setObjectName("verticalLayout_3")
- self.groupBox = QtWidgets.QGroupBox(self.projectWidget)
+ self.groupBox = QtWidgets.QGroupBox(parent=self.projectWidget)
self.groupBox.setEnabled(True)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Fixed)
+ sizePolicy.setHorizontalStretch(1)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.groupBox.sizePolicy().hasHeightForWidth())
self.groupBox.setSizePolicy(sizePolicy)
self.groupBox.setMinimumSize(QtCore.QSize(0, 20))
self.groupBox.setBaseSize(QtCore.QSize(0, 30))
- self.groupBox.setFlat(True)
+ self.groupBox.setFlat(False)
self.groupBox.setObjectName("groupBox")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.groupBox)
self.horizontalLayout.setObjectName("horizontalLayout")
- self.addTrace = QtWidgets.QPushButton(self.groupBox)
+ self.addTrace = QtWidgets.QPushButton(parent=self.groupBox)
+ self.addTrace.setAcceptDrops(True)
self.addTrace.setAutoFillBackground(False)
- self.addTrace.setText("")
icon = QtGui.QIcon.fromTheme("list-add")
self.addTrace.setIcon(icon)
self.addTrace.setDefault(True)
- self.addTrace.setFlat(True)
+ self.addTrace.setFlat(False)
self.addTrace.setObjectName("addTrace")
self.horizontalLayout.addWidget(self.addTrace)
- self.removeTrace = QtWidgets.QPushButton(self.groupBox)
- self.removeTrace.setText("")
+ self.removeTrace = QtWidgets.QPushButton(parent=self.groupBox)
icon = QtGui.QIcon.fromTheme("list-remove")
self.removeTrace.setIcon(icon)
- self.removeTrace.setFlat(True)
+ self.removeTrace.setFlat(False)
self.removeTrace.setObjectName("removeTrace")
self.horizontalLayout.addWidget(self.removeTrace)
- self.recalculateEvents = QtWidgets.QPushButton(self.groupBox)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
+ self.recalculateEvents = QtWidgets.QPushButton(parent=self.groupBox)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed)
+ sizePolicy.setHorizontalStretch(1)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.recalculateEvents.sizePolicy().hasHeightForWidth())
self.recalculateEvents.setSizePolicy(sizePolicy)
icon = QtGui.QIcon.fromTheme("view-refresh")
self.recalculateEvents.setIcon(icon)
- self.recalculateEvents.setFlat(True)
+ self.recalculateEvents.setFlat(False)
self.recalculateEvents.setObjectName("recalculateEvents")
self.horizontalLayout.addWidget(self.recalculateEvents)
- self.saveProject = QtWidgets.QPushButton(self.groupBox)
- icon = QtGui.QIcon.fromTheme("document-save")
+ self.saveProject = QtWidgets.QPushButton(parent=self.groupBox)
+ self.saveProject.setAutoFillBackground(False)
+ icon = QtGui.QIcon.fromTheme("media-floppy")
self.saveProject.setIcon(icon)
- self.saveProject.setFlat(True)
+ self.saveProject.setFlat(False)
self.saveProject.setObjectName("saveProject")
self.horizontalLayout.addWidget(self.saveProject)
- self.openProject = QtWidgets.QPushButton(self.groupBox)
+ self.openProject = QtWidgets.QPushButton(parent=self.groupBox)
icon = QtGui.QIcon.fromTheme("folder-open")
self.openProject.setIcon(icon)
- self.openProject.setFlat(True)
+ self.openProject.setFlat(False)
self.openProject.setObjectName("openProject")
self.horizontalLayout.addWidget(self.openProject)
- self.printReport = QtWidgets.QPushButton(self.groupBox)
- icon = QtGui.QIcon.fromTheme("document-print")
+ self.printReport = QtWidgets.QPushButton(parent=self.groupBox)
+ icon = QtGui.QIcon.fromTheme("QIcon::ThemeIcon::Printer")
self.printReport.setIcon(icon)
- self.printReport.setFlat(True)
+ self.printReport.setFlat(False)
self.printReport.setObjectName("printReport")
self.horizontalLayout.addWidget(self.printReport)
self.verticalLayout_3.addWidget(self.groupBox)
- self.treeView = QtWidgets.QTreeView(self.projectWidget)
+ self.treeView = QtWidgets.QTreeView(parent=self.projectWidget)
self.treeView.setObjectName("treeView")
self.verticalLayout_3.addWidget(self.treeView)
self.tabWidget.addTab(self.projectWidget, "")
@@ -99,34 +96,21 @@ def setupUi(self, MainWindow):
self.metaDataWidget.setObjectName("metaDataWidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.metaDataWidget)
self.verticalLayout.setObjectName("verticalLayout")
- self.metaDataTable = QtWidgets.QTableWidget(self.metaDataWidget)
- self.metaDataTable.setObjectName("metaDataTable")
- self.metaDataTable.setColumnCount(0)
- self.metaDataTable.setRowCount(9)
- item = QtWidgets.QTableWidgetItem()
- self.metaDataTable.setVerticalHeaderItem(0, item)
- item = QtWidgets.QTableWidgetItem()
- self.metaDataTable.setVerticalHeaderItem(1, item)
- item = QtWidgets.QTableWidgetItem()
- self.metaDataTable.setVerticalHeaderItem(2, item)
- item = QtWidgets.QTableWidgetItem()
- self.metaDataTable.setVerticalHeaderItem(3, item)
- item = QtWidgets.QTableWidgetItem()
- self.metaDataTable.setVerticalHeaderItem(4, item)
- item = QtWidgets.QTableWidgetItem()
- self.metaDataTable.setVerticalHeaderItem(5, item)
- item = QtWidgets.QTableWidgetItem()
- self.metaDataTable.setVerticalHeaderItem(6, item)
- item = QtWidgets.QTableWidgetItem()
- self.metaDataTable.setVerticalHeaderItem(7, item)
- item = QtWidgets.QTableWidgetItem()
- self.metaDataTable.setVerticalHeaderItem(8, item)
- self.verticalLayout.addWidget(self.metaDataTable)
+ self.metaTableView = QtWidgets.QTableView(parent=self.metaDataWidget)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding)
+ sizePolicy.setHorizontalStretch(1)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.metaTableView.sizePolicy().hasHeightForWidth())
+ self.metaTableView.setSizePolicy(sizePolicy)
+ self.metaTableView.setMinimumSize(QtCore.QSize(300, 200))
+ self.metaTableView.setSortingEnabled(True)
+ self.metaTableView.setObjectName("metaTableView")
+ self.verticalLayout.addWidget(self.metaTableView)
self.tabWidget.addTab(self.metaDataWidget, "")
self.horizontalLayout_3.addWidget(self.tabWidget)
- self.dataWidget = QtWidgets.QWidget(self.mainWidget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
+ self.dataWidget = QtWidgets.QWidget(parent=self.mainWidget)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding)
+ sizePolicy.setHorizontalStretch(1)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.dataWidget.sizePolicy().hasHeightForWidth())
self.dataWidget.setSizePolicy(sizePolicy)
@@ -134,9 +118,9 @@ def setupUi(self, MainWindow):
self.dataWidget.setObjectName("dataWidget")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.dataWidget)
self.verticalLayout_2.setObjectName("verticalLayout_2")
- self.graphWidget = QtWidgets.QWidget(self.dataWidget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
+ self.graphWidget = QtWidgets.QWidget(parent=self.dataWidget)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding)
+ sizePolicy.setHorizontalStretch(1)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.graphWidget.sizePolicy().hasHeightForWidth())
self.graphWidget.setSizePolicy(sizePolicy)
@@ -148,12 +132,12 @@ def setupUi(self, MainWindow):
self.graphLayout.setObjectName("graphLayout")
self.horizontalLayout_2.addLayout(self.graphLayout)
self.verticalLayout_2.addWidget(self.graphWidget)
- self.widget = QtWidgets.QWidget(self.dataWidget)
+ self.widget = QtWidgets.QWidget(parent=self.dataWidget)
self.widget.setObjectName("widget")
self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.widget)
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
- self.eventTableView = QtWidgets.QTableView(self.widget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
+ self.eventTableView = QtWidgets.QTableView(parent=self.widget)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding)
sizePolicy.setHorizontalStretch(1)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.eventTableView.sizePolicy().hasHeightForWidth())
@@ -165,7 +149,7 @@ def setupUi(self, MainWindow):
self.verticalLayout_2.addWidget(self.widget)
self.horizontalLayout_3.addWidget(self.dataWidget)
MainWindow.setCentralWidget(self.mainWidget)
- self.statusbar = QtWidgets.QStatusBar(MainWindow)
+ self.statusbar = QtWidgets.QStatusBar(parent=MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
@@ -176,25 +160,19 @@ def setupUi(self, MainWindow):
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
+ self.addTrace.setToolTip(_translate("MainWindow", "Add Trace"))
+ self.addTrace.setText(_translate("MainWindow", "+"))
+ self.removeTrace.setToolTip(_translate("MainWindow", "Remove Trace"))
+ self.removeTrace.setText(_translate("MainWindow", "-"))
+ self.recalculateEvents.setToolTip(_translate("MainWindow", "Calculate Events"))
+ self.recalculateEvents.setText(_translate("MainWindow", "calc"))
+ self.saveProject.setToolTip(_translate("MainWindow", "Save Project"))
+ self.saveProject.setText(_translate("MainWindow", "save"))
+ self.openProject.setToolTip(_translate("MainWindow", "Open Project"))
+ self.openProject.setText(_translate("MainWindow", "open"))
+ self.printReport.setToolTip(_translate("MainWindow", "Print"))
+ self.printReport.setText(_translate("MainWindow", "print"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.projectWidget), _translate("MainWindow", "Project"))
- item = self.metaDataTable.verticalHeaderItem(0)
- item.setText(_translate("MainWindow", "Project name"))
- item = self.metaDataTable.verticalHeaderItem(1)
- item.setText(_translate("MainWindow", "Location A"))
- item = self.metaDataTable.verticalHeaderItem(2)
- item.setText(_translate("MainWindow", "Location B"))
- item = self.metaDataTable.verticalHeaderItem(3)
- item.setText(_translate("MainWindow", "Total distance (km)"))
- item = self.metaDataTable.verticalHeaderItem(4)
- item.setText(_translate("MainWindow", "Total distance"))
- item = self.metaDataTable.verticalHeaderItem(5)
- item.setText(_translate("MainWindow", "Launch length (km)"))
- item = self.metaDataTable.verticalHeaderItem(6)
- item.setText(_translate("MainWindow", "Recieve length (km)"))
- item = self.metaDataTable.verticalHeaderItem(7)
- item.setText(_translate("MainWindow", "Average loss (dB/km)"))
- item = self.metaDataTable.verticalHeaderItem(8)
- item.setText(_translate("MainWindow", "Total loss(dB)"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.metaDataWidget), _translate("MainWindow", "Meta Data"))
@@ -205,4 +183,4 @@ def retranslateUi(self, MainWindow):
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
- sys.exit(app.exec_())
+ sys.exit(app.exec())
diff --git a/mainwindow.ui b/mainwindow.ui
index f5f99e6..d7947bd 100644
--- a/mainwindow.ui
+++ b/mainwindow.ui
@@ -7,7 +7,7 @@
0
0
1280
- 755
+ 760
@@ -19,7 +19,7 @@
- 0
+ 1
0
@@ -29,9 +29,6 @@
720
-
- QTabWidget::West
-
0
@@ -47,7 +44,7 @@
- 0
+ 1
0
@@ -64,42 +61,47 @@
- true
+ false
-
+
+ true
+
+
+ Add Trace
+
false
-
+ +
-
-
-
+
true
- true
+ false
-
+
+ Remove Trace
+
-
+ -
-
-
-
+
- true
+ false
@@ -107,53 +109,72 @@
- 0
+ 1
0
+
+ Calculate Events
+
+
+ calc
+
-
-
-
+
- true
+ false
-
+
+ Save Project
+
+
+ false
+
+
+ save
+
-
-
-
+
- true
+ false
-
+
+ Open Project
+
+
+ open
+
-
-
-
+
- true
+ false
-
+
+ Print
+
+
+ print
+
-
-
-
+
- true
+ false
@@ -171,53 +192,23 @@
-
-
-
-
- Project name
-
-
-
-
- Location A
-
-
-
-
- Location B
-
-
-
-
- Total distance (km)
-
-
-
-
- Total distance
-
-
-
-
- Launch length (km)
-
-
-
-
- Recieve length (km)
-
-
-
-
- Average loss (dB/km)
-
-
-
-
- Total loss(dB)
-
-
-
+
+
+
+ 1
+ 0
+
+
+
+
+ 300
+ 200
+
+
+
+ true
+
+
@@ -227,7 +218,7 @@
- 0
+ 1
0
@@ -242,7 +233,7 @@
- 0
+ 1
0
@@ -265,7 +256,7 @@
-
-
+
1
0
diff --git a/requirements.txt b/requirements.txt
index 3042185..156a511 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,6 @@
-scipy==1.10.1
-matplotlib==3.6.3
-pyotdr==1.0.0
-numpy==1.24.2
-PyQt5==*
+scipy
+matplotlib
+#pyotdr==1.0.0
+otdrparser
+numpy
+PyQt6