diff --git a/pyqt/stabwindow.ui b/pyqt/stabwindow.ui index ef2ea7e4b47d2682123d76d0013502bffc95162f..14ca7b463bdfebcec3ff6d063be266509e9b372a 100644 --- a/pyqt/stabwindow.ui +++ b/pyqt/stabwindow.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>1074</width> - <height>685</height> + <width>1338</width> + <height>713</height> </rect> </property> <property name="windowTitle"> @@ -62,8 +62,8 @@ <rect> <x>10</x> <y>50</y> - <width>871</width> - <height>621</height> + <width>1321</width> + <height>651</height> </rect> </property> </widget> diff --git a/src/gui/uistabwindow.py b/src/gui/uistabwindow.py index 69ec70b107040fc33dbec9474eb2eba507dd97a5..99144acc7aa6f2de5b10651466d84f48d4019c7c 100644 --- a/src/gui/uistabwindow.py +++ b/src/gui/uistabwindow.py @@ -11,7 +11,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets class Ui_StabWindow(object): def setupUi(self, StabWindow): StabWindow.setObjectName("StabWindow") - StabWindow.resize(1074, 685) + StabWindow.resize(1338, 713) self.horizontalLayoutWidget = QtWidgets.QWidget(StabWindow) self.horizontalLayoutWidget.setGeometry(QtCore.QRect(10, 10, 461, 31)) self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget") @@ -33,7 +33,7 @@ class Ui_StabWindow(object): self.stab_combobox_variable.setObjectName("stab_combobox_variable") self.horizontalLayout.addWidget(self.stab_combobox_variable) self.stab_graphicsview = PlotWidget(StabWindow) - self.stab_graphicsview.setGeometry(QtCore.QRect(10, 50, 871, 621)) + self.stab_graphicsview.setGeometry(QtCore.QRect(10, 50, 1321, 651)) self.stab_graphicsview.setObjectName("stab_graphicsview") self.retranslateUi(StabWindow) diff --git a/src/uim/explouim.py b/src/uim/explouim.py index 16764c5b3c7b5ab6c9e20b6da8ff952d5393fd73..4c78f1008244ca2347f04b2541d8c66007c64158 100644 --- a/src/uim/explouim.py +++ b/src/uim/explouim.py @@ -204,6 +204,8 @@ class ExploUim: combobox.addItem(instrument_name) def __update_variables_combobox__(self, combobox_text: str, combobox: QComboBox): + if combobox_text == "": + return # variables_combobox = self.main_ui.explo_tablewidget_variables.cellWidget(row, self.VARIABLE_COL) variables_combobox = combobox variables_combobox.clear() @@ -547,6 +549,7 @@ class ExploUim: self.stab_plot_item.addItem(self.stab_step_curve) self.stab_window.ui.stab_graphicsview.setCentralItem(self.stab_plot_item) + # Left self.stab_region_left = pg.LinearRegionItem(brush=pg.mkBrush(color=[0, 0, 255, 40])) self.stab_region_left.setZValue(10) self.stab_plot_item.addItem(self.stab_region_left, ignoreBounds=True) @@ -555,6 +558,7 @@ class ExploUim: self.stab_left_mean_line = pg.InfiniteLine(pen=pg.mkPen(color=[0, 0, 255]), angle=0) self.stab_plot_item.addItem(self.stab_left_mean_line) + # Right self.stab_region_right = pg.LinearRegionItem(brush=pg.mkBrush(color=[0, 255, 0, 40])) self.stab_region_right.setZValue(10) self.stab_plot_item.addItem(self.stab_region_right, ignoreBounds=True) @@ -563,6 +567,22 @@ class ExploUim: self.stab_right_mean_line = pg.InfiniteLine(pen=pg.mkPen(color=[0, 255, 0]), angle=0) self.stab_plot_item.addItem(self.stab_right_mean_line) + # High + self.stab_high_hline = pg.InfiniteLine(pen=pg.mkPen(color=[255, 0, 0], style=Qt.DotLine), angle=0) + self.stab_plot_item.addItem(self.stab_high_hline) + self.stab_high_vline = pg.InfiniteLine(pen=pg.mkPen(color=[255, 0, 0], style=Qt.DotLine), angle=90) + self.stab_plot_item.addItem(self.stab_high_vline) + + # Low + self.stab_low_hline = pg.InfiniteLine(pen=pg.mkPen(color=[255, 0, 0], style=Qt.DotLine), angle=0) + self.stab_plot_item.addItem(self.stab_low_hline) + self.stab_low_vline = pg.InfiniteLine(pen=pg.mkPen(color=[255, 0, 0], style=Qt.DotLine), angle=90) + self.stab_plot_item.addItem(self.stab_low_vline) + + # Time delta text + self.stab_time_text = pg.TextItem(anchor=(0.5,1)) + self.stab_plot_item.addItem(self.stab_time_text) + self.stab_timeseries = pd.DataFrame() def __update_stab_plot__(self, var_combobox_text: str): @@ -575,7 +595,7 @@ class ExploUim: # Get data instrument_log = self.current_dataset.instlogs[self.stab_window.ui.stab_combobox_instrument.currentText()] variable_name = self.stab_window.ui.stab_combobox_variable.currentText() - self.stab_timeseries = instrument_log.get_timeseries(variable_name) + self.stab_timeseries = instrument_log.get_timeseries(variable_name).copy() # Set data to step curve x_values = self.__get_timeseries_x_values__(self.stab_timeseries) @@ -583,34 +603,86 @@ class ExploUim: y=self.__get_timeseries_y_values__(self.stab_timeseries), stepMode=True) + # Convert data in a form more convenient for plot + self.stab_timeseries["datetime"] = utils.pd_time_to_epoch_ms(self.stab_timeseries["datetime"]) + if not is_numeric_dtype(self.stab_timeseries["value"]): + self.stab_timeseries["value"] = self.stab_timeseries["value_int"] + + # Get the main windows view box + main_range = self.plot_item.getViewBox().viewRange() + # Place the 2 (right/left) regions - x_min = min(x_values) - x_max = max(x_values) + x_min = main_range[0][0] + x_max = main_range[0][1] x_1_third = x_min + ((x_max - x_min) / 3) x_2_third = x_min + 2 * ((x_max - x_min) / 3) self.stab_region_left.setRegion([x_min, x_1_third]) self.stab_region_right.setRegion([x_2_third, x_max]) + # Re-calculate the position of the left/right means + self.__update_stab_mean__(self.stab_region_left, "left") + self.__update_stab_mean__(self.stab_region_right, "right") + + # X range is the same as main window's plot X range + self.stab_plot_item.getViewBox().setRange(xRange=(main_range[0][0], main_range[0][1]), + yRange=(main_range[1][0], main_range[1][1]), + padding=0) + def __update_stab_mean__(self, region: pg.LinearRegionItem, side: str): df = self.stab_timeseries.copy() + + # Get the selected region's boundaries xmin = region.getRegion()[0] xmax = region.getRegion()[1] - df["datetime"] = utils.pd_time_to_epoch_ms(df["datetime"]) - if is_numeric_dtype(df["value"]): - x_value_var_name = "value" - else: - x_value_var_name = "value_int" - mean = df[(df["datetime"] >= xmin) & (df["datetime"] <= xmax)][x_value_var_name].mean() + # Compute x_value's average over the selected region. + mean = df[(df["datetime"] >= xmin) & (df["datetime"] <= xmax)]["value"].mean() if math.isnan(mean): return + # Update global "mean" variable setattr(self, "stab_" + side + "_mean", mean) # Update 'mean' horizontal line position line = getattr(self, "stab_" + side + "_mean_line") line.setValue(mean) + self.__compute_stab_delta__() + def __compute_stab_delta__(self): - pass + # Left + left_mean = self.stab_left_mean + right_mean = self.stab_right_mean + + high_y = max(left_mean, right_mean) + low_y = min(left_mean, right_mean) + ten_prct = (high_y - low_y) * 0.1 + + high_minus_ten = high_y - ten_prct + low_plus_ten = low_y + ten_prct + + # Find timeseries' value where crossing 'high_minus_ten' and 'low_plus_ten' + df = self.stab_timeseries.copy() + + # Keep only the data between both regions. + df = df[(df["datetime"] > self.stab_region_left.getRegion()[1]) + & (df["datetime"] < self.stab_region_right.getRegion()[0]) + & (df["value"] < high_minus_ten) + & (df["value"] > low_plus_ten)] + if df.empty: + return + + high_datetime = df.loc[df["value"].idxmax()]["datetime"] + low_datetime = df.loc[df["value"].idxmin()]["datetime"] + + # Plot lines + self.stab_high_hline.setValue(high_minus_ten) + self.stab_low_hline.setValue(low_plus_ten) + self.stab_high_vline.setValue(high_datetime) + self.stab_low_vline.setValue(low_datetime) + # Add text + time_delta = high_datetime - low_datetime + self.stab_time_text.setText("<-- " + "{:.2f}".format(time_delta) + "s -->") + self.stab_time_text.setPos(low_datetime + (high_datetime-low_datetime)/2, + high_y)