dev: функционал разделен на подготовительный этап (настройка фильтра) и финальный по соответствующим кнопкам (open filder и calc TCW)
This commit is contained in:
parent
86c7c8d1e6
commit
90b6660a15
@ -3,10 +3,10 @@
|
||||
0.008
|
||||
],
|
||||
"actuator_zero_velocity_trashold": [
|
||||
10.0
|
||||
100.0
|
||||
],
|
||||
"actuator_finishing_velocity": [
|
||||
2050.0
|
||||
2000.0
|
||||
],
|
||||
"actuator_finishing_velocity_trashold": [
|
||||
200.0
|
||||
|
||||
@ -104,7 +104,12 @@ class BaseMediator:
|
||||
data: Union[list[str], list[pd.DataFrame], list[list], list[QWidget], pd.DataFrame]):
|
||||
...
|
||||
|
||||
def prerender(self, data:list[str]) -> None:
|
||||
def prerender_TCW(self, source:Union[BaseController, BaseFileManager, BaseRawTraceProcessor],
|
||||
data:Union[str, list[str], list[pd.DataFrame, dict]]) -> None:
|
||||
...
|
||||
|
||||
def render_TCW(self, source:Union[BaseController, BaseRawTraceProcessor],
|
||||
data:Union[str, list[pd.DataFrame, dict]]) -> None:
|
||||
...
|
||||
|
||||
def set_mode(self, mode: int) -> None:
|
||||
@ -282,7 +287,8 @@ class BaseFileManager:
|
||||
monitor: Optional[BaseDirectoryMonitor] = None):
|
||||
self._mediator = mediator
|
||||
self._monitor = monitor
|
||||
self._paths_library = set()
|
||||
self._paths_library:set = set()
|
||||
self._mode = 0
|
||||
|
||||
@property
|
||||
def paths_library(self) -> set:
|
||||
@ -471,10 +477,12 @@ class BaseRawTraceProcessor:
|
||||
self._trace_df = None
|
||||
self._text_data = None
|
||||
|
||||
|
||||
def prerender(self, data:list[str]) -> None:
|
||||
...
|
||||
|
||||
def final_render(self) -> None:
|
||||
...
|
||||
|
||||
def update_settings(self, data:Settings) -> None:
|
||||
...
|
||||
|
||||
|
||||
@ -33,7 +33,10 @@ class Controller(BaseController):
|
||||
self._file_manager.open_custom_file(filepath)
|
||||
|
||||
def open_dir(self, dirpath:str) -> None:
|
||||
self._file_manager.open_raw_traces_dir(dirpath)
|
||||
self._mediator.prerender_TCW(self, dirpath)
|
||||
|
||||
def build_TCW_for_client(self):
|
||||
self._mediator.render_TCW(self)
|
||||
|
||||
def save_file(self, data:list[str, QTabWidget]) -> None:
|
||||
filepath, tab = data
|
||||
|
||||
@ -9,7 +9,8 @@ class FileManager(BaseFileManager):
|
||||
|
||||
def replot_all(self) -> None:
|
||||
if self._paths_library is not None:
|
||||
self._mediator.notify(self, list(self._paths_library))
|
||||
if self._mode != 3: self._mediator.notify(self, list(self._paths_library))
|
||||
else: self.open_raw_traces_dir(list(self._paths_library)[0])
|
||||
|
||||
def open_custom_file(self, path:str) -> None:
|
||||
self._paths_library.add(path)
|
||||
@ -22,14 +23,17 @@ class FileManager(BaseFileManager):
|
||||
self._paths_library.clear()
|
||||
self._paths_library.add('')
|
||||
self._mediator.notify(self, list(self._paths_library))
|
||||
self._mode = 1
|
||||
|
||||
case 2: # Режим онлайн-мониторинга папки
|
||||
self._monitor.init_state()
|
||||
self._monitor.start()
|
||||
self._mode = 2
|
||||
|
||||
case 3: # Режим работы с трейсами клиента
|
||||
self._monitor.stop()
|
||||
self._paths_library.clear()
|
||||
self._mode = 3
|
||||
|
||||
def update_monitor_settings(self, settings:Settings) -> None:
|
||||
directory_path = settings.system['trace_storage_path'][0]
|
||||
@ -54,6 +58,8 @@ class FileManager(BaseFileManager):
|
||||
self._mediator.notify(list(new))
|
||||
|
||||
def open_raw_traces_dir(self, path:str) -> None:
|
||||
self._paths_library.clear()
|
||||
self._paths_library.add(path)
|
||||
dat_file, txt_file = None, None
|
||||
for entry in os.listdir(path):
|
||||
full_path = os.path.join(path, entry)
|
||||
@ -69,7 +75,7 @@ class FileManager(BaseFileManager):
|
||||
break
|
||||
|
||||
if dat_file and txt_file:
|
||||
self._mediator.prerender([dat_file, txt_file])
|
||||
self._mediator.prerender_TCW(self, [dat_file, txt_file])
|
||||
|
||||
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@ class Mediator(BaseMediator):
|
||||
|
||||
def notify(self,
|
||||
source: Union[BaseFileManager, BaseDataConverter, BasePointPassportFormer, BasePlotWidget, BaseController, BaseRawTraceProcessor],
|
||||
data: Union[list[str], list[pd.DataFrame], list[GraphicPassport], list[QWidget], Settings, pd.DataFrame]):
|
||||
data: Union[list[str], list[pd.DataFrame], list[GraphicPassport], list[QWidget], Settings, pd.DataFrame]) -> None:
|
||||
|
||||
if issubclass(source.__class__, BaseFileManager):
|
||||
self._controller.update_status("CSV found! Calculating...")
|
||||
@ -31,7 +31,7 @@ class Mediator(BaseMediator):
|
||||
self._passport_former.form_passports(data)
|
||||
|
||||
if issubclass(source.__class__, BasePointPassportFormer):
|
||||
self._controller.update_progress(2)
|
||||
self._controller.update_progress(10)
|
||||
self._plot.build(data)
|
||||
|
||||
if issubclass(source.__class__, BasePlotWidget):
|
||||
@ -42,13 +42,33 @@ class Mediator(BaseMediator):
|
||||
self._file_manager.update_monitor_settings(data)
|
||||
self._passport_former.update_settings(data)
|
||||
self._trace_processor.update_settings(data)
|
||||
|
||||
def prerender_TCW(self, source:Union[BaseController, BaseFileManager, BaseRawTraceProcessor],
|
||||
data:Union[str, list[str], list[pd.DataFrame, dict]]) -> None:
|
||||
|
||||
if issubclass(source.__class__, BaseController):
|
||||
self._controller.update_progress(5)
|
||||
self._file_manager.open_raw_traces_dir(data)
|
||||
|
||||
if issubclass(source.__class__, BaseFileManager):
|
||||
self._controller.update_progress(15)
|
||||
self._trace_processor.prerender(data)
|
||||
|
||||
if issubclass(source.__class__, BaseRawTraceProcessor):
|
||||
self._controller.update_progress(40)
|
||||
self._plot.build_raw_trace(data)
|
||||
|
||||
def render_TCW(self, source:Union[BaseController, BaseRawTraceProcessor],
|
||||
data:Union[str, list[pd.DataFrame, dict]] = None) -> None:
|
||||
|
||||
if issubclass(source.__class__, BaseController):
|
||||
self._controller.update_progress(5)
|
||||
self._trace_processor.final_render()
|
||||
|
||||
if issubclass(source.__class__, BaseRawTraceProcessor):
|
||||
self._controller.update_progress(5)
|
||||
self._passport_former.form_customer_passport(data)
|
||||
|
||||
def prerender(self, data:list[str]) -> None:
|
||||
self._trace_processor.prerender(data)
|
||||
|
||||
|
||||
def set_mode(self, mode: int) -> None:
|
||||
self._plot.set_mode(mode)
|
||||
self._file_manager.set_mode(mode)
|
||||
|
||||
@ -19,6 +19,7 @@ class MainWindow(BaseMainWindow):
|
||||
signal_open_file = pyqtSignal(str)
|
||||
signal_save_file = pyqtSignal(list)
|
||||
signal_open_dir = pyqtSignal(str)
|
||||
signal_TCW_for_client = pyqtSignal()
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
@ -118,9 +119,11 @@ class MainWindow(BaseMainWindow):
|
||||
#TODO: привязать действия к кнопкам
|
||||
client_widget.open_folder_btn.clicked.connect(self._open_folder)
|
||||
client_widget.save_screen_btn.clicked.connect(self._save_plots)
|
||||
client_widget.build_TCW_btn.clicked.connect(self._build_TCW_for_client)
|
||||
self.setCentralWidget(client_widget.get_widget())
|
||||
#client_widget.build_TCW_btn.clicked.connect()
|
||||
|
||||
|
||||
def _build_TCW_for_client(self):
|
||||
self.signal_TCW_for_client.emit()
|
||||
|
||||
def _set_mode(self, num:int) -> None:
|
||||
match num:
|
||||
|
||||
@ -63,7 +63,7 @@ class PlotWidget(BasePlotWidget):
|
||||
finally:
|
||||
self._mediator.notify(self, widgets_datapack)
|
||||
|
||||
def build_raw_trace(self, data:pd.DataFrame) -> None:
|
||||
def build_raw_trace(self, data:list[pd.DataFrame, dict]) -> None:
|
||||
"""
|
||||
Создаёт один виджет с одним графиком, где представлены все данные
|
||||
"""
|
||||
@ -87,17 +87,28 @@ class PlotWidget(BasePlotWidget):
|
||||
print(3)
|
||||
|
||||
def _build_raw_plotitem(self,
|
||||
dataframe:pd.DataFrame,
|
||||
data:list[pd.DataFrame, dict],
|
||||
pyqt_container:PlotItems) -> pg.GraphicsLayoutWidget:
|
||||
|
||||
plot_item, legend = PlotItemGenerator._init_plot_item("Customer data")
|
||||
dataframe, events = data
|
||||
channels = dataframe.columns.to_list()
|
||||
for i, channel in enumerate(channels):
|
||||
plot = plot_item.plot(dataframe.index.values, dataframe[channel], pen = qts.colors[i], fast = True)
|
||||
plot = plot_item.plot(dataframe["time"], dataframe[channel], pen = qts.colors[i], fast = True)
|
||||
legend.addItem(plot, channel)
|
||||
pyqt_container.curves["real"].setdefault(channel, {})
|
||||
pyqt_container.curves["real"][channel] = plot
|
||||
|
||||
for i in range(len(events["Squeeze"][0])):
|
||||
point_events = {}
|
||||
for key, item in events.items():
|
||||
point_events[key] = [item[0][i], item[1][i]]
|
||||
PlotItemGenerator._add_stage_regions(self._stage_colors, plot_item, point_events, pyqt_container.regions,20)
|
||||
print(point_events)
|
||||
|
||||
plot_layout = pg.GraphicsLayoutWidget()
|
||||
plot_layout.addItem(plot_item)
|
||||
|
||||
return plot_layout
|
||||
|
||||
def _build_performance_label(self,
|
||||
@ -269,7 +280,7 @@ class PlotItemGenerator:
|
||||
dataframe = self._apply_force_compensation(force, k_hardness, dataframe, point_data.timeframe, signals)
|
||||
|
||||
if settings.get("stages", False):
|
||||
self._add_stage_regions(plot_item, point_data.events, dataframe_headers, pyqt_container.regions, 75)
|
||||
self._add_stage_regions(self._stage_colors, plot_item, point_data.events, pyqt_container.regions, 75)
|
||||
|
||||
if settings.get("force accuracy", False):
|
||||
force = point_data.useful_data["force"]
|
||||
@ -283,7 +294,7 @@ class PlotItemGenerator:
|
||||
self._add_workpiece(point_data, plot_item)
|
||||
|
||||
if settings.get("ideals", False):
|
||||
self._add_ideal_stage_regions(plot_item, ideal_data, point_data.events, pyqt_container.regions, 100)
|
||||
self._add_ideal_stage_regions(self._stage_colors, plot_item, ideal_data, point_data.events, pyqt_container.regions, 100)
|
||||
self._add_ideal_signals(plot_item, legend, ideal_data, point_data.events, description["Ideal_signals"], pyqt_container.curves, is_last)
|
||||
|
||||
if settings.get("performance", False):
|
||||
@ -333,7 +344,8 @@ class PlotItemGenerator:
|
||||
)
|
||||
return None
|
||||
|
||||
def _create_stage_region(self,
|
||||
@staticmethod
|
||||
def _create_stage_region(colors:dict,
|
||||
stage: str,
|
||||
start_timestamp: float,
|
||||
finish_timestamp: float,
|
||||
@ -343,32 +355,33 @@ class PlotItemGenerator:
|
||||
"""
|
||||
if start_timestamp is not None and finish_timestamp is not None:
|
||||
region = pg.LinearRegionItem([start_timestamp, finish_timestamp], movable=False)
|
||||
color = self._stage_colors.get(stage, [100, 100, 100, 100])
|
||||
color = colors.get(stage, [100, 100, 100, 100])
|
||||
region.setBrush(pg.mkBrush(color[:3] + [transparency]))
|
||||
return region
|
||||
return None
|
||||
|
||||
def _add_stage_regions(self,
|
||||
@staticmethod
|
||||
def _add_stage_regions(colors:dict,
|
||||
plot_item: pg.PlotItem,
|
||||
point_events: dict[str, list[float]],
|
||||
dataframe_headers: list[str],
|
||||
point_events: dict,
|
||||
reg_items: dict,
|
||||
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:
|
||||
region.setZValue(-20)
|
||||
plot_item.addItem(region)
|
||||
reg_items["real"].setdefault(stage, [])
|
||||
reg_items["real"][stage].append(region)
|
||||
#if all(stage in dataframe_headers for stage in stages):
|
||||
for stage in stages:
|
||||
start_t, end_t = point_events[stage]
|
||||
region = PlotItemGenerator._create_stage_region(colors, stage, start_t, end_t, transparency)
|
||||
if region is not None:
|
||||
region.setZValue(-20)
|
||||
plot_item.addItem(region)
|
||||
reg_items["real"].setdefault(stage, [])
|
||||
reg_items["real"][stage].append(region)
|
||||
|
||||
def _add_ideal_stage_regions(self,
|
||||
@staticmethod
|
||||
def _add_ideal_stage_regions(colors: dict,
|
||||
plot_item: pg.PlotItem,
|
||||
ideal_data: dict[str, Any],
|
||||
point_events: dict[str, list[float]],
|
||||
@ -382,7 +395,7 @@ class PlotItemGenerator:
|
||||
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)
|
||||
region = PlotItemGenerator._create_stage_region(colors, stage, start_t, end_t, transparency)
|
||||
if region:
|
||||
region.setZValue(-10)
|
||||
plot_item.addItem(region)
|
||||
|
||||
@ -33,6 +33,7 @@ def main():
|
||||
window.signal_open_file.connect(controller.open_file)
|
||||
window.signal_open_dir.connect(controller.open_dir)
|
||||
window.signal_save_file.connect(controller.save_file)
|
||||
window.signal_TCW_for_client.connect(controller.build_TCW_for_client)
|
||||
|
||||
controller.signal_widgets.connect(window.show_plot_tabs)
|
||||
controller.signal_progress_bar.connect(window.status_widget.set_progress)
|
||||
|
||||
@ -261,6 +261,18 @@ class TraceProcessor(BaseRawTraceProcessor):
|
||||
super().__init__(dataparser, textparser, data_detector, text_detector)
|
||||
|
||||
def prerender(self, data:list[str]) -> None:
|
||||
|
||||
rendered_data = self._render_data(data)
|
||||
self._mediator.prerender_TCW(self, rendered_data)
|
||||
|
||||
def final_render(self) -> None:
|
||||
|
||||
events = self._detect_stages(self._trace_df, self._text_data)
|
||||
dataframe = self._rename_df_columns(self._trace_df)
|
||||
self._mediator.render_TCW(self, [dataframe, events])
|
||||
|
||||
def _render_data(self, data:list[str]) -> list[pd.DataFrame, dict]:
|
||||
|
||||
if data and len(data) == 2:
|
||||
dat_filepath = data[0]
|
||||
txt_filepath = data[1]
|
||||
@ -271,12 +283,11 @@ class TraceProcessor(BaseRawTraceProcessor):
|
||||
dat_filepath = None
|
||||
txt_filepath = None
|
||||
|
||||
trace_df = self._unpack_trace(dat_filepath)
|
||||
text_data = self._unpack_text(txt_filepath)
|
||||
events = self._detect_stages(trace_df, text_data)
|
||||
dataframe = self._rename_df_columns(trace_df)
|
||||
|
||||
self._mediator.notify(self, [dataframe, events])
|
||||
self._trace_df = self._unpack_trace(dat_filepath)
|
||||
self._text_data = self._unpack_text(txt_filepath)
|
||||
events = self._detect_stages(self._trace_df, self._text_data)
|
||||
dataframe = self._rename_df_columns(self._trace_df)
|
||||
return [dataframe, events]
|
||||
|
||||
def update_settings(self, data:Settings) -> None:
|
||||
self._settings = data
|
||||
@ -359,7 +370,7 @@ class TraceProcessor(BaseRawTraceProcessor):
|
||||
"Rotor Current, A ME": ["DriveMotorCurr_Act7"],
|
||||
"Cartesian Tool Speed, mm/s ME": ["CartVel_Act"],
|
||||
}
|
||||
|
||||
dataframe = dataframe.copy(deep=True)
|
||||
working_mapping = {key: [item.lower() for item in items] for key, items in correct_mapping.items()}
|
||||
|
||||
try:
|
||||
|
||||
@ -455,6 +455,16 @@ QLabel {
|
||||
}"""
|
||||
|
||||
colors = [
|
||||
'#FF6F61', # яркий коралловый
|
||||
'#6B5B95', # приглушенный фиолетовый
|
||||
'#88B04B', # яркий зеленый
|
||||
'#F7CAC9', # светлый розовый
|
||||
'#92A8D1', # светло-голубой
|
||||
'#955251', # теплый терракотовый
|
||||
'#B565A7', # лавандовый
|
||||
'#009B77', # глубокий бирюзовый
|
||||
'#DD4124', # ярко-красный
|
||||
'#45B8AC', # мягкий мятный
|
||||
'#FF6F61', # яркий коралловый
|
||||
'#6B5B95', # приглушенный фиолетовый
|
||||
'#88B04B', # яркий зеленый
|
||||
|
||||
Loading…
Reference in New Issue
Block a user