2024-12-24 18:45:07 +03:00
|
|
|
|
from PyQt5.QtWidgets import (QWidget, QVBoxLayout,
|
|
|
|
|
|
QHBoxLayout, QLabel,
|
|
|
|
|
|
QGraphicsRectItem, QSpacerItem,
|
|
|
|
|
|
QSizePolicy)
|
|
|
|
|
|
|
|
|
|
|
|
from PyQt5.QtCore import Qt
|
2024-12-16 13:59:42 +03:00
|
|
|
|
import copy
|
2024-12-24 16:25:50 +03:00
|
|
|
|
import traceback
|
|
|
|
|
|
import sys
|
|
|
|
|
|
from loguru import logger
|
2024-11-25 14:01:09 +03:00
|
|
|
|
import pyqtgraph as pg
|
2024-12-18 10:16:50 +03:00
|
|
|
|
import pandas as pd
|
2024-12-09 16:05:34 +03:00
|
|
|
|
from typing import Optional, Any
|
2024-11-25 14:01:09 +03:00
|
|
|
|
|
2024-12-05 13:18:53 +03:00
|
|
|
|
from utils.base.base import BasePlotWidget
|
2024-11-25 17:20:00 +03:00
|
|
|
|
|
2024-12-09 16:05:34 +03:00
|
|
|
|
class ProcessStage():
|
|
|
|
|
|
mean_value:int
|
|
|
|
|
|
start_index:int
|
|
|
|
|
|
finish_index:int
|
2024-11-25 14:01:09 +03:00
|
|
|
|
|
2024-12-04 20:01:30 +03:00
|
|
|
|
class PlotWidget(BasePlotWidget):
|
2024-11-25 14:01:09 +03:00
|
|
|
|
|
2024-12-09 16:05:34 +03:00
|
|
|
|
def _create_curve_ideal(self,
|
|
|
|
|
|
signal: dict[str, Any],
|
|
|
|
|
|
ideal_data: pd.DataFrame,
|
|
|
|
|
|
start_timestamp: float,
|
|
|
|
|
|
finish_timestamp: float) -> Optional[pg.PlotDataItem]:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Создаёт идеальную кривую для сигнала, если заданы корректные временные рамки.
|
|
|
|
|
|
"""
|
|
|
|
|
|
if start_timestamp is not None and finish_timestamp is not None:
|
|
|
|
|
|
return pg.PlotDataItem(
|
|
|
|
|
|
x=start_timestamp + ideal_data["time"],
|
|
|
|
|
|
y=ideal_data[signal["name"]],
|
|
|
|
|
|
pen=signal["pen"]
|
|
|
|
|
|
)
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
2024-11-25 14:01:09 +03:00
|
|
|
|
def _create_stage_region(self,
|
|
|
|
|
|
stage: str,
|
2024-12-02 11:04:15 +03:00
|
|
|
|
start_timestamp: float,
|
2024-12-05 12:02:07 +03:00
|
|
|
|
finish_timestamp: float,
|
2024-12-09 16:05:34 +03:00
|
|
|
|
transparency: int) -> Optional[pg.LinearRegionItem]:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Создает регион для определённого этапа, если заданы временные рамки.
|
|
|
|
|
|
"""
|
|
|
|
|
|
if start_timestamp is not None and finish_timestamp is not None:
|
2024-12-02 11:04:15 +03:00
|
|
|
|
region = pg.LinearRegionItem([start_timestamp, finish_timestamp], movable=False)
|
2024-12-09 16:05:34 +03:00
|
|
|
|
color = self._stage_colors.get(stage, [100, 100, 100, 100])
|
|
|
|
|
|
region.setBrush(pg.mkBrush(color[:3] + [transparency]))
|
2024-12-02 11:04:15 +03:00
|
|
|
|
return region
|
|
|
|
|
|
return None
|
2024-11-25 14:01:09 +03:00
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
2024-12-18 14:54:40 +03:00
|
|
|
|
def _init_plot_item(title: str) -> tuple[pg.PlotItem, pg.LegendItem]:
|
|
|
|
|
|
plot_item = pg.PlotItem(title=title)
|
2024-12-09 16:05:34 +03:00
|
|
|
|
# Оптимизация отображения графиков
|
2024-12-18 14:54:40 +03:00
|
|
|
|
plot_item.setDownsampling(auto=True, mode='peak')
|
|
|
|
|
|
plot_item.showGrid(x=True, y=True)
|
|
|
|
|
|
plot_item.setClipToView(True)
|
|
|
|
|
|
legend = plot_item.addLegend(offset=(70, 20))
|
|
|
|
|
|
return plot_item, legend
|
2024-11-25 14:01:09 +03:00
|
|
|
|
|
2024-12-09 16:05:34 +03:00
|
|
|
|
def _add_stage_regions(self,
|
2024-12-18 14:54:40 +03:00
|
|
|
|
plot_item: pg.PlotItem,
|
2024-12-09 16:05:34 +03:00
|
|
|
|
point_events: dict[str, list[float]],
|
|
|
|
|
|
dataframe_headers: list[str],
|
2024-12-17 20:40:04 +03:00
|
|
|
|
reg_items: dict,
|
2024-12-09 16:05:34 +03:00
|
|
|
|
transparency: int = 75) -> None:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Добавляет регионы для реальных этапов, если все стадии есть в заголовках датафрейма.
|
|
|
|
|
|
"""
|
|
|
|
|
|
stages = point_events.keys()
|
|
|
|
|
|
if all(stage in dataframe_headers for stage in stages):
|
|
|
|
|
|
for stage in stages:
|
|
|
|
|
|
start_t, end_t = point_events[stage]
|
|
|
|
|
|
region = self._create_stage_region(stage, start_t, end_t, transparency)
|
|
|
|
|
|
if region is not None:
|
2024-12-17 15:27:03 +03:00
|
|
|
|
region.setZValue(-20)
|
2024-12-18 14:54:40 +03:00
|
|
|
|
plot_item.addItem(region)
|
2024-12-17 20:40:04 +03:00
|
|
|
|
reg_items["real"].setdefault(stage, [])
|
|
|
|
|
|
reg_items["real"][stage].append(region)
|
2024-12-09 16:05:34 +03:00
|
|
|
|
|
|
|
|
|
|
def _add_ideal_stage_regions(self,
|
2024-12-18 14:54:40 +03:00
|
|
|
|
plot_item: pg.PlotItem,
|
2024-12-09 16:05:34 +03:00
|
|
|
|
ideal_data: dict[str, Any],
|
|
|
|
|
|
point_events: dict[str, list[float]],
|
2024-12-17 20:40:04 +03:00
|
|
|
|
reg_items: dict,
|
2024-12-09 16:05:34 +03:00
|
|
|
|
transparency: int = 125) -> None:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Добавляет регионы для идеальных этапов.
|
|
|
|
|
|
"""
|
|
|
|
|
|
ideal_timings = ideal_data["Ideal timings"]
|
|
|
|
|
|
stages = list(point_events.keys())
|
|
|
|
|
|
for i, stage in enumerate(stages):
|
|
|
|
|
|
start_t = point_events[stage][0]
|
|
|
|
|
|
end_t = start_t + ideal_timings[i]
|
|
|
|
|
|
region = self._create_stage_region(stage, start_t, end_t, transparency)
|
|
|
|
|
|
if region:
|
2024-12-17 15:27:03 +03:00
|
|
|
|
region.setZValue(-10)
|
2024-12-18 14:54:40 +03:00
|
|
|
|
plot_item.addItem(region)
|
2024-12-17 20:40:04 +03:00
|
|
|
|
reg_items["ideal"].setdefault(stage, [])
|
|
|
|
|
|
reg_items["ideal"][stage].append(region)
|
2024-12-09 16:05:34 +03:00
|
|
|
|
|
|
|
|
|
|
def _add_ideal_signals(self,
|
2024-12-18 14:54:40 +03:00
|
|
|
|
plot_item: pg.PlotItem,
|
2024-12-26 13:47:26 +03:00
|
|
|
|
legend_item: pg.LegendItem,
|
2024-12-09 16:05:34 +03:00
|
|
|
|
ideal_data: dict[str, Any],
|
|
|
|
|
|
point_events: dict[str, list[float]],
|
2024-12-17 20:40:04 +03:00
|
|
|
|
ideal_signals: list[dict[str, Any]],
|
2024-12-26 13:47:26 +03:00
|
|
|
|
curve_items: dict,
|
|
|
|
|
|
is_last: bool) -> None:
|
2024-12-09 16:05:34 +03:00
|
|
|
|
"""
|
|
|
|
|
|
Добавляет идеальные сигналы для каждого этапа.
|
|
|
|
|
|
"""
|
2024-12-26 13:47:26 +03:00
|
|
|
|
for signal in ideal_signals:
|
|
|
|
|
|
for stage in point_events.keys():
|
2024-12-09 16:05:34 +03:00
|
|
|
|
curve = self._create_curve_ideal(
|
|
|
|
|
|
signal,
|
|
|
|
|
|
ideal_data[stage],
|
|
|
|
|
|
point_events[stage][0],
|
|
|
|
|
|
point_events[stage][1]
|
|
|
|
|
|
)
|
|
|
|
|
|
if curve:
|
2024-12-19 13:23:27 +03:00
|
|
|
|
curve.setZValue(50)
|
2024-12-18 14:54:40 +03:00
|
|
|
|
plot_item.addItem(curve)
|
2024-12-17 20:40:04 +03:00
|
|
|
|
curve_items["ideal"].setdefault(signal["name"], {})
|
2024-12-18 12:44:43 +03:00
|
|
|
|
curve_items["ideal"][signal["name"]].setdefault(stage, [])
|
|
|
|
|
|
curve_items["ideal"][signal["name"]][stage].append(curve)
|
2024-12-26 13:47:26 +03:00
|
|
|
|
if is_last: legend_item.addItem(curve, "Ideal " + signal["name"])
|
2024-12-17 20:40:04 +03:00
|
|
|
|
|
2024-12-09 16:05:34 +03:00
|
|
|
|
def _add_real_signals(self,
|
2024-12-18 14:54:40 +03:00
|
|
|
|
plot_item: pg.PlotItem,
|
2024-12-09 16:05:34 +03:00
|
|
|
|
dataframe: pd.DataFrame,
|
|
|
|
|
|
real_signals: list[dict[str, Any]],
|
2024-12-17 20:40:04 +03:00
|
|
|
|
legend: pg.LegendItem,
|
|
|
|
|
|
curve_items: dict) -> None:
|
2024-12-09 16:05:34 +03:00
|
|
|
|
"""
|
|
|
|
|
|
Добавляет реальные сигналы из dataframe на виджет.
|
|
|
|
|
|
"""
|
|
|
|
|
|
dataframe_headers = dataframe.columns.tolist()
|
|
|
|
|
|
for signal in real_signals:
|
|
|
|
|
|
if signal["name"] in dataframe_headers:
|
2024-12-18 14:54:40 +03:00
|
|
|
|
plot = plot_item.plot(dataframe["time"], dataframe[signal["name"]], pen=signal["pen"], fast=True)
|
2024-12-17 15:27:03 +03:00
|
|
|
|
plot.setZValue(0)
|
2024-12-09 16:05:34 +03:00
|
|
|
|
legend.addItem(plot, signal["name"])
|
2024-12-17 20:40:04 +03:00
|
|
|
|
curve_items["real"].setdefault(signal["name"], {})
|
|
|
|
|
|
curve_items["real"][signal["name"]] = plot
|
2024-12-09 16:05:34 +03:00
|
|
|
|
|
|
|
|
|
|
def _add_performance_label(self,
|
|
|
|
|
|
layout: QVBoxLayout,
|
|
|
|
|
|
TWC_time: float,
|
|
|
|
|
|
ideal_time: float,
|
2024-12-24 18:45:07 +03:00
|
|
|
|
tesla_time: float,
|
|
|
|
|
|
qt_items: dict) -> None:
|
2024-12-09 16:05:34 +03:00
|
|
|
|
"""
|
|
|
|
|
|
Добавляет QLabel с информацией о производительности.
|
|
|
|
|
|
"""
|
|
|
|
|
|
tesla_TWC = round((1 - TWC_time/tesla_time)*100, 2) if tesla_time else 0.0
|
|
|
|
|
|
tesla_ideal = round((1 - ideal_time/tesla_time)*100, 2) if tesla_time else 0.0
|
|
|
|
|
|
TWC_ideal = round((ideal_time/TWC_time)*100, 2) if TWC_time else 0.0
|
2024-12-24 18:45:07 +03:00
|
|
|
|
|
|
|
|
|
|
label_widget = QWidget()
|
|
|
|
|
|
label_layout = QHBoxLayout(label_widget)
|
|
|
|
|
|
start_label = QLabel("Сокращение длительности: ")
|
|
|
|
|
|
real_label = QLabel(f"фактическое = {tesla_TWC} % ")
|
2024-12-25 16:47:35 +03:00
|
|
|
|
if not tesla_TWC or not TWC_time: real_label.setVisible(False)
|
2024-12-24 18:45:07 +03:00
|
|
|
|
ideal_label = QLabel(f"идеальное = {tesla_ideal} % ")
|
2024-12-25 16:47:35 +03:00
|
|
|
|
if not tesla_ideal: ideal_label.setVisible(False)
|
2024-12-24 18:45:07 +03:00
|
|
|
|
kdip_label = QLabel(f"КДИП = {TWC_ideal}% ")
|
2024-12-25 16:47:35 +03:00
|
|
|
|
if not TWC_ideal: kdip_label.setVisible(False)
|
2024-12-24 18:45:07 +03:00
|
|
|
|
label_layout.addWidget(start_label, alignment=Qt.AlignLeft)
|
|
|
|
|
|
label_layout.addWidget(real_label, alignment=Qt.AlignLeft)
|
|
|
|
|
|
label_layout.addWidget(ideal_label, alignment=Qt.AlignLeft)
|
|
|
|
|
|
label_layout.addWidget(kdip_label, alignment=Qt.AlignLeft)
|
|
|
|
|
|
spacer = QSpacerItem(1, 1, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
|
|
|
|
label_layout.addSpacerItem(spacer)
|
|
|
|
|
|
|
|
|
|
|
|
self.set_style(label_widget)
|
|
|
|
|
|
layout.addWidget(label_widget)
|
|
|
|
|
|
|
|
|
|
|
|
qt_items["performance label"] = label_widget
|
|
|
|
|
|
qt_items["real performance"] = real_label
|
|
|
|
|
|
qt_items["ideal performance"] = ideal_label
|
|
|
|
|
|
qt_items["real to ideal performance"] = kdip_label
|
2024-12-09 16:05:34 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _build_widget(self, data: list[Any]) -> QWidget:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Собирает графический виджет для одного набора данных.
|
2024-12-16 13:59:42 +03:00
|
|
|
|
Параметр `data` предполагается списком: [dataframe, points_pocket, useful_data].
|
2024-12-09 16:05:34 +03:00
|
|
|
|
"""
|
2024-12-18 14:54:40 +03:00
|
|
|
|
result_widget = QWidget()
|
|
|
|
|
|
result_layout = QVBoxLayout(result_widget)
|
|
|
|
|
|
plot_layout = pg.GraphicsLayoutWidget()
|
2024-12-17 20:40:04 +03:00
|
|
|
|
reg_items = {"real":{}, "ideal":{}}
|
|
|
|
|
|
curve_items = {"real":{}, "ideal":{}}
|
2024-12-24 18:45:07 +03:00
|
|
|
|
qt_items = {}
|
2024-12-09 16:05:34 +03:00
|
|
|
|
|
2024-12-16 13:59:42 +03:00
|
|
|
|
dataframe, points_pocket, useful_data = data
|
|
|
|
|
|
tesla_time = useful_data["tesla_time"]
|
2024-12-27 18:25:27 +03:00
|
|
|
|
gun_range = useful_data["range"]
|
|
|
|
|
|
|
2024-12-16 16:49:01 +03:00
|
|
|
|
k_hardness = useful_data["k_hardness"]
|
2024-12-19 13:23:27 +03:00
|
|
|
|
|
|
|
|
|
|
dat_is_none = dataframe is None
|
|
|
|
|
|
|
2024-12-25 11:56:17 +03:00
|
|
|
|
widget_steps = len(self._plt_channels)
|
|
|
|
|
|
|
|
|
|
|
|
if not dat_is_none:
|
|
|
|
|
|
dataframe_headers = dataframe.columns.tolist()
|
|
|
|
|
|
point_steps = len(points_pocket)
|
|
|
|
|
|
else: point_steps = 1
|
2024-12-09 16:05:34 +03:00
|
|
|
|
|
|
|
|
|
|
for widget_num, (channel, description) in enumerate(self._plt_channels.items()):
|
2024-12-18 14:54:40 +03:00
|
|
|
|
plot_item, legend = self._init_plot_item(title=channel)
|
2024-11-25 14:01:09 +03:00
|
|
|
|
settings = description["Settings"]
|
2024-12-25 16:47:35 +03:00
|
|
|
|
global_shift = 0
|
2024-12-09 16:05:34 +03:00
|
|
|
|
TWC_time = 0.0
|
|
|
|
|
|
ideal_time = 0.0
|
|
|
|
|
|
worst_perf = 2
|
2024-12-16 13:59:42 +03:00
|
|
|
|
|
2024-12-16 15:09:45 +03:00
|
|
|
|
# TODO: рассчитать корректный параметр range
|
2024-12-19 13:23:27 +03:00
|
|
|
|
if settings["mirror ME"] and not dat_is_none:
|
2024-12-18 14:54:40 +03:00
|
|
|
|
dataframe = self._mirror_shift_data(
|
|
|
|
|
|
"ME",
|
|
|
|
|
|
description["Real_signals"],
|
|
|
|
|
|
dataframe,
|
2024-12-27 18:25:27 +03:00
|
|
|
|
gun_range
|
2024-12-18 14:54:40 +03:00
|
|
|
|
)
|
2024-12-16 15:09:45 +03:00
|
|
|
|
|
2024-12-09 16:05:34 +03:00
|
|
|
|
# Итерация по точкам
|
|
|
|
|
|
for cur_point, point_data in enumerate(points_pocket):
|
2024-12-18 15:08:23 +03:00
|
|
|
|
# point_data структура: [point_timeframe, ideal_data, point_events, useful_p_data]
|
2024-12-16 14:24:26 +03:00
|
|
|
|
point_timeframe, ideal_dat, point_events, useful_p_data = point_data
|
2024-12-16 13:59:42 +03:00
|
|
|
|
ideal_data = copy.deepcopy(ideal_dat)
|
2024-12-19 13:23:27 +03:00
|
|
|
|
|
|
|
|
|
|
if dat_is_none:
|
2024-12-25 16:47:35 +03:00
|
|
|
|
worst_timeframe = point_timeframe = [global_shift, global_shift+ ideal_data["Ideal cycle"]]
|
2024-12-19 13:23:27 +03:00
|
|
|
|
point_events = {}
|
|
|
|
|
|
keys = list(ideal_data.keys())
|
|
|
|
|
|
shift = 0
|
|
|
|
|
|
for i, time in enumerate(ideal_data["Ideal timings"]):
|
2024-12-25 16:47:35 +03:00
|
|
|
|
point_events[keys[i]] = [global_shift+shift, global_shift+time+shift]
|
2024-12-19 13:23:27 +03:00
|
|
|
|
shift += time
|
2024-12-25 16:47:35 +03:00
|
|
|
|
global_shift +=ideal_data["Ideal cycle"]
|
2024-12-19 13:23:27 +03:00
|
|
|
|
|
2024-12-16 15:09:45 +03:00
|
|
|
|
# TODO: проверить корректность расчетов
|
2024-12-27 18:25:27 +03:00
|
|
|
|
if False and settings["force compensation FE"] and not dat_is_none:
|
2024-12-16 15:09:45 +03:00
|
|
|
|
force = useful_p_data["force"]
|
2024-12-16 16:49:01 +03:00
|
|
|
|
F_comp = - force/k_hardness
|
2024-12-16 15:09:45 +03:00
|
|
|
|
point_idxs = dataframe[(dataframe["time"] >= point_timeframe[0]) & (dataframe["time"] <= point_timeframe[1])].index
|
|
|
|
|
|
|
|
|
|
|
|
dataframe.loc[point_idxs] = self._shift_data("FE", description["Real_signals"], dataframe.loc[point_idxs], F_comp)
|
2024-12-16 14:24:26 +03:00
|
|
|
|
|
2024-12-16 13:59:42 +03:00
|
|
|
|
# Модифицируем данные для отображения гарфика
|
|
|
|
|
|
if settings["ideals"] and settings["mirror ME"]:
|
|
|
|
|
|
for stage in point_events.keys():
|
2024-12-27 18:25:27 +03:00
|
|
|
|
ideal_data[stage] = (
|
|
|
|
|
|
self._mirror_shift_ideal("ME", "FE", description["Ideal_signals"],
|
|
|
|
|
|
ideal_data[stage],
|
|
|
|
|
|
gun_range, useful_p_data["P1"]*1000, useful_p_data["P2"]*1000)
|
|
|
|
|
|
)
|
2024-12-16 13:59:42 +03:00
|
|
|
|
|
2024-12-09 16:05:34 +03:00
|
|
|
|
# Добавляем реальные стадии
|
2024-12-19 13:23:27 +03:00
|
|
|
|
if settings["stages"] and not dat_is_none:
|
2024-12-18 14:54:40 +03:00
|
|
|
|
self._add_stage_regions(plot_item, point_events, dataframe_headers, reg_items, 75)
|
2024-12-04 20:01:30 +03:00
|
|
|
|
|
2024-12-16 14:24:26 +03:00
|
|
|
|
if settings["workpiece"]:
|
|
|
|
|
|
x1 = point_timeframe[0]
|
|
|
|
|
|
dx = point_timeframe[1] - x1
|
2024-12-27 17:38:50 +03:00
|
|
|
|
y1 = useful_p_data["position"]*1000
|
2024-12-16 14:24:26 +03:00
|
|
|
|
dy = useful_p_data["thickness"]*1000
|
2024-12-16 15:09:45 +03:00
|
|
|
|
|
2024-12-16 14:24:26 +03:00
|
|
|
|
rect_item = QGraphicsRectItem(x1, y1, dx, dy)
|
2024-12-17 15:27:03 +03:00
|
|
|
|
rect_item.setZValue(-5)
|
|
|
|
|
|
rect_item.setBrush(pg.mkBrush('grey'))
|
|
|
|
|
|
rect_item.setPen(pg.mkPen('black', width=3))
|
2024-12-18 14:54:40 +03:00
|
|
|
|
plot_item.addItem(rect_item)
|
2024-12-16 14:24:26 +03:00
|
|
|
|
|
2024-12-19 13:23:27 +03:00
|
|
|
|
if settings["force accuracy"]and not dat_is_none:
|
2024-12-18 13:52:05 +03:00
|
|
|
|
modifier = 0.05
|
|
|
|
|
|
|
|
|
|
|
|
x1 = point_events["Welding"][0]
|
|
|
|
|
|
dx = point_events["Welding"][1] - x1
|
|
|
|
|
|
force = useful_p_data["force"]
|
|
|
|
|
|
y1 = force*(1-modifier)
|
|
|
|
|
|
dy = force*(2*modifier)
|
|
|
|
|
|
|
|
|
|
|
|
rect_item = QGraphicsRectItem(x1, y1, dx, dy)
|
|
|
|
|
|
rect_item.setZValue(-5)
|
|
|
|
|
|
rect_item.setBrush(pg.mkBrush((0,255,0, 50)))
|
|
|
|
|
|
rect_item.setPen(pg.mkPen('black', width=0))
|
2024-12-18 14:54:40 +03:00
|
|
|
|
plot_item.addItem(rect_item)
|
2024-12-18 13:52:05 +03:00
|
|
|
|
|
2024-12-09 16:05:34 +03:00
|
|
|
|
# Добавляем идеальные стадии и идеальные сигналы
|
2024-12-04 20:01:30 +03:00
|
|
|
|
if settings["ideals"]:
|
2024-12-26 13:47:26 +03:00
|
|
|
|
is_last_point = (cur_point == len(points_pocket) - 1)
|
2024-12-18 14:54:40 +03:00
|
|
|
|
self._add_ideal_stage_regions(plot_item, ideal_data, point_events, reg_items, 100)
|
2024-12-26 13:47:26 +03:00
|
|
|
|
self._add_ideal_signals(plot_item, legend, ideal_data, point_events, description["Ideal_signals"], curve_items, is_last_point)
|
2024-12-03 17:21:22 +03:00
|
|
|
|
|
2024-12-09 16:05:34 +03:00
|
|
|
|
# Подсчёт производительности
|
2024-12-25 16:47:35 +03:00
|
|
|
|
if settings["performance"]:
|
2024-12-09 16:05:34 +03:00
|
|
|
|
is_last_point = (cur_point == len(points_pocket) - 1)
|
|
|
|
|
|
if is_last_point:
|
2024-12-25 16:47:35 +03:00
|
|
|
|
if not dat_is_none: TWC_delta = sum([point_events[stage][1] - point_events[stage][0]
|
|
|
|
|
|
for stage in ["Closing", "Squeeze", "Welding"]])
|
|
|
|
|
|
else: TWC_delta = 0
|
|
|
|
|
|
ideal_delta = sum(ideal_data["Ideal timings"][0:3])
|
2024-12-04 20:01:30 +03:00
|
|
|
|
else:
|
2024-12-25 16:47:35 +03:00
|
|
|
|
if not dat_is_none: TWC_delta = point_timeframe[1] - point_timeframe[0]
|
|
|
|
|
|
else: TWC_delta = 0
|
2024-12-09 16:05:34 +03:00
|
|
|
|
ideal_delta = ideal_data["Ideal cycle"]
|
2024-12-25 16:47:35 +03:00
|
|
|
|
|
2024-12-09 16:05:34 +03:00
|
|
|
|
TWC_time += TWC_delta
|
|
|
|
|
|
ideal_time += ideal_delta
|
|
|
|
|
|
curr_perf = ideal_delta/TWC_delta if TWC_delta != 0 else 1
|
2024-12-18 15:08:23 +03:00
|
|
|
|
|
2024-12-09 16:05:34 +03:00
|
|
|
|
if curr_perf < worst_perf:
|
|
|
|
|
|
worst_perf = curr_perf
|
|
|
|
|
|
worst_timeframe = point_timeframe
|
2024-12-25 16:47:35 +03:00
|
|
|
|
|
2024-12-06 11:12:08 +03:00
|
|
|
|
|
2024-12-25 11:56:17 +03:00
|
|
|
|
# Считаем прогресс
|
|
|
|
|
|
self._update_status(widget_steps, point_steps, widget_num, cur_point)
|
|
|
|
|
|
|
2024-12-09 16:05:34 +03:00
|
|
|
|
# Добавляем реальные сигналы
|
2024-12-19 13:23:27 +03:00
|
|
|
|
if not dat_is_none:
|
|
|
|
|
|
self._add_real_signals(plot_item, dataframe, description["Real_signals"], legend, curve_items)
|
2024-12-09 16:05:34 +03:00
|
|
|
|
if widget_num == 0:
|
2024-12-18 14:54:40 +03:00
|
|
|
|
main_plot = plot_item
|
2024-12-09 16:05:34 +03:00
|
|
|
|
else:
|
|
|
|
|
|
# Связываем остальные графики с основным графиком
|
2024-12-18 14:54:40 +03:00
|
|
|
|
plot_item.setXLink(main_plot)
|
2024-12-06 11:12:08 +03:00
|
|
|
|
|
2024-12-25 16:47:35 +03:00
|
|
|
|
if settings["performance"]:
|
2024-12-24 18:45:07 +03:00
|
|
|
|
self._add_performance_label(result_layout, TWC_time, ideal_time, tesla_time, qt_items)
|
2024-12-18 14:54:40 +03:00
|
|
|
|
|
|
|
|
|
|
plot_layout.addItem(plot_item, widget_num, 0)
|
2024-12-18 15:08:23 +03:00
|
|
|
|
|
|
|
|
|
|
navigator, ROI_region = self._create_navigator(worst_timeframe, main_plot)
|
|
|
|
|
|
if navigator is not None:
|
|
|
|
|
|
plot_layout.addItem(navigator, widget_num+1, 0)
|
|
|
|
|
|
self._sync_main_plot_with_navigator(main_plot, ROI_region)
|
|
|
|
|
|
main_plot.sigXRangeChanged.connect(lambda _, plot=main_plot, region=ROI_region: self._sync_navigator_with_main(main_plot=plot, region=region))
|
2024-12-09 16:05:34 +03:00
|
|
|
|
|
2024-12-18 14:54:40 +03:00
|
|
|
|
result_layout.addWidget(plot_layout)
|
2024-12-24 18:45:07 +03:00
|
|
|
|
return result_widget, reg_items, curve_items, qt_items
|
2024-11-25 14:01:09 +03:00
|
|
|
|
|
2024-12-09 16:05:34 +03:00
|
|
|
|
def build(self, data: list[list[Any]]) -> None:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Создает набор виджетов по предоставленному списку данных.
|
|
|
|
|
|
Предполагается, что data — это список элементов вида:
|
|
|
|
|
|
[
|
2024-12-18 12:58:37 +03:00
|
|
|
|
[dataframe, points_pocket, useful_data],
|
|
|
|
|
|
[dataframe, points_pocket, useful_data],
|
2024-12-09 16:05:34 +03:00
|
|
|
|
...
|
|
|
|
|
|
]
|
|
|
|
|
|
"""
|
2024-12-24 16:25:50 +03:00
|
|
|
|
try:
|
2024-12-25 11:56:17 +03:00
|
|
|
|
self._datalen = len(data)
|
|
|
|
|
|
widgets_datapack = [self._build_widget(data_sample) for self._datastep, data_sample in enumerate(data)]
|
2024-12-24 16:25:50 +03:00
|
|
|
|
except:
|
|
|
|
|
|
tb = sys.exc_info()[2]
|
|
|
|
|
|
tbinfo = traceback.format_tb(tb)[0]
|
|
|
|
|
|
pymsg = "Traceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1])
|
|
|
|
|
|
logger.error(pymsg)
|
|
|
|
|
|
widgets_datapack = [QLabel(pymsg)]
|
|
|
|
|
|
finally:
|
|
|
|
|
|
self._mediator.notify(self, widgets_datapack)
|
2024-12-17 20:40:04 +03:00
|
|
|
|
|
2024-12-25 11:56:17 +03:00
|
|
|
|
def _update_status(self, widgsteps:int, pointsteps:int, cur_widg:int, cur_point:int):
|
|
|
|
|
|
if self._datalen != 0:
|
|
|
|
|
|
sycle_start = self._datastep/self._datalen*100 + 1
|
|
|
|
|
|
period1 = 100/self._datalen
|
|
|
|
|
|
else:
|
|
|
|
|
|
sycle_start = 1
|
|
|
|
|
|
period1 = 100
|
|
|
|
|
|
|
|
|
|
|
|
period2 = period1/widgsteps if widgsteps != 0 else period1
|
|
|
|
|
|
period3 = period2/pointsteps if pointsteps != 0 else period2
|
|
|
|
|
|
|
|
|
|
|
|
progress = sycle_start + period2*cur_widg + period3*cur_point
|
|
|
|
|
|
self._mediator.update_status(progress)
|
|
|
|
|
|
|
2024-11-25 14:01:09 +03:00
|
|
|
|
|
2024-12-17 20:40:04 +03:00
|
|
|
|
|