Skip to content
Snippets Groups Projects
Commit 3de03613 authored by VulcanixFR's avatar VulcanixFR
Browse files

Add button to compute predictive indicators from GUI

parent 971ba374
No related merge requests found
...@@ -12,7 +12,8 @@ import re ...@@ -12,7 +12,8 @@ import re
from .database import Database from .database import Database
from .processing import * from .processing import *
from .plots import * from .plots import *
from time import time from time import time, mktime
from datetime import datetime
# %% - Constants # %% - Constants
QUERY_DROP_TABLE = lambda r: f"drop table if exists Robot{r}_indicators;" QUERY_DROP_TABLE = lambda r: f"drop table if exists Robot{r}_indicators;"
...@@ -31,8 +32,13 @@ COMPUTED_COLUMS = [ ...@@ -31,8 +32,13 @@ COMPUTED_COLUMS = [
# COMPUTED_COLUMS.append(f"{v}_A{m}") # COMPUTED_COLUMS.append(f"{v}_A{m}")
QUERY_INDICATORS = lambda r: f"SELECT * FROM Robot{r}_indicators;" QUERY_INDICATORS = lambda r: f"SELECT * FROM Robot{r}_indicators;"
QUERY_ROBOTS = "SELECT DISTINCT `Robot` from DataFiles"
# %% - Computation for one run # %% - Computation for one run
def compute_run (DB: Database, robot: int, run: int, t0: int, date: str): def compute_run (DB: Database, robot: int, run: int, t0: int, date: str, next: Callable[[str], None] = None):
if next is not None:
next(f"Robot {robot} run n°{run} from {date}")
out = [] out = []
...@@ -43,6 +49,7 @@ def compute_run (DB: Database, robot: int, run: int, t0: int, date: str): ...@@ -43,6 +49,7 @@ def compute_run (DB: Database, robot: int, run: int, t0: int, date: str):
data[data["MovingMotor"] == m] for m in range(1,7) data[data["MovingMotor"] == m] for m in range(1,7)
] ]
runTime = t0 + mktime(datetime.strptime(date, "%Y-%m-%d").timetuple())
# Compute for whole experiment # Compute for whole experiment
# line = [ t0, 0 ] # line = [ t0, 0 ]
for m in range(1,7): for m in range(1,7):
...@@ -51,7 +58,7 @@ def compute_run (DB: Database, robot: int, run: int, t0: int, date: str): ...@@ -51,7 +58,7 @@ def compute_run (DB: Database, robot: int, run: int, t0: int, date: str):
temp = sub[f"Temperature_A{m}"].to_numpy() temp = sub[f"Temperature_A{m}"].to_numpy()
line = [ line = [
# *line, # *line,
t0, t0, 0, data["Class"][0], date, runTime, runTime, 0, data["Class"][0], date,
f"A{m}", RMS(c), kmeans(c), peak_factor(c), np.mean(temp) f"A{m}", RMS(c), kmeans(c), peak_factor(c), np.mean(temp)
] ]
out.append(line) out.append(line)
...@@ -69,12 +76,13 @@ def compute_run (DB: Database, robot: int, run: int, t0: int, date: str): ...@@ -69,12 +76,13 @@ def compute_run (DB: Database, robot: int, run: int, t0: int, date: str):
# line = [ time, s ] # line = [ time, s ]
for m in range(1,7): for m in range(1,7):
sub = d[d["MovingMotor"] == m] sub = d[d["MovingMotor"] == m]
time = d["Sample_time"].to_numpy()[0] + t0 time = d["Sample_time"].to_numpy()[0] + runTime
c = sub[f"Current_A{m}"].to_numpy() c = sub[f"Current_A{m}"].to_numpy()
temp = sub[f"Temperature_A{m}"].to_numpy() temp = sub[f"Temperature_A{m}"].to_numpy()
line = [ line = [
# *line, # *line,
time, t0, s, data["Class"][0], date, time, runTime, s, data["Class"][0], date,
f"A{m}", RMS(c), kmeans(c), peak_factor(c), np.mean(temp) f"A{m}", RMS(c), kmeans(c), peak_factor(c), np.mean(temp)
] ]
out.append(line) out.append(line)
...@@ -83,7 +91,7 @@ def compute_run (DB: Database, robot: int, run: int, t0: int, date: str): ...@@ -83,7 +91,7 @@ def compute_run (DB: Database, robot: int, run: int, t0: int, date: str):
return out return out
# %% - Transformation function # %% - Transformation function
def compute_indicators (DB: Database, robot: int): def compute_indicators (DB: Database, robot: int, next: Callable[[str], None] = None):
if not (1 <= robot <= 3): if not (1 <= robot <= 3):
print("Robot must be between 1 and 3") print("Robot must be between 1 and 3")
...@@ -104,10 +112,24 @@ def compute_indicators (DB: Database, robot: int): ...@@ -104,10 +112,24 @@ def compute_indicators (DB: Database, robot: int):
out = [] out = []
for i, run in enumerate(runs): for i, run in enumerate(runs):
print("Robot", robot, "run n°", run) print("Robot", robot, "run n°", run)
out = [ *out, *compute_run(DB, robot, run, times[i], dates[i]) ] out = [ *out, *compute_run(DB, robot, run, times[i], dates[i], next) ]
# Save # Save
df = pd.DataFrame(out, columns=COMPUTED_COLUMS) df = pd.DataFrame(out, columns=COMPUTED_COLUMS)
df.to_sql(f"Robot{robot}_indicators", DB.db) df.to_sql(f"Robot{robot}_indicators", DB.db)
return df return df
#%%
def compute_indicators_all_robots (DB: Database, next: Callable[[str], None] = None):
if (next is not None):
print("Has next function")
next("Initializing ...")
robots: List[str] = pd.read_sql(QUERY_ROBOTS, DB.db)["Robot"].to_list()
for robot in robots:
print("Calculating indicators for", robot)
n = int(robot.split("_")[1])
compute_indicators(DB, n, next)
\ No newline at end of file
...@@ -4,7 +4,10 @@ ...@@ -4,7 +4,10 @@
import PySimpleGUI as sg import PySimpleGUI as sg
from pathlib import Path from pathlib import Path
from threading import Thread, Semaphore
from tools.database import Database, init_database from tools.database import Database, init_database
from tools.predictive_indicators import compute_indicators_all_robots
from .DB_Metadata import DBFileManagerWindow from .DB_Metadata import DBFileManagerWindow
class DBSelectWin (sg.Window): class DBSelectWin (sg.Window):
...@@ -15,6 +18,14 @@ class DBSelectWin (sg.Window): ...@@ -15,6 +18,14 @@ class DBSelectWin (sg.Window):
self.edit_window = None self.edit_window = None
self.indicator_popup: sg.Window = None
self.indicator_popup_lock = Semaphore()
self.indicator_progress: int = 0
self.indicator_max_progress: int = 0
self.indicator_run_name: str = "None"
self.db_use_done = False
super().__init__("Database Selector", self._layout(), finalize=True) super().__init__("Database Selector", self._layout(), finalize=True)
self.update_display() self.update_display()
...@@ -25,7 +36,7 @@ class DBSelectWin (sg.Window): ...@@ -25,7 +36,7 @@ class DBSelectWin (sg.Window):
self.buttons = { self.buttons = {
"-open-close-": sg.Button("Open", key="-open-close-"), "-open-close-": sg.Button("Open", key="-open-close-"),
"-edit-": sg.Button("Edit Data", key="-edit-"), "-edit-": sg.Button("Edit Data", key="-edit-"),
"-plot-": sg.Button("Plot Data", key="-plot-"), "-indicators-": sg.Button("Compute indicators", key="-indicators-"),
"-new-": sg.Button("New Database", key="-new-"), "-new-": sg.Button("New Database", key="-new-"),
"-browse-": sg.FileBrowse( "-browse-": sg.FileBrowse(
key="-browse-", key="-browse-",
...@@ -47,7 +58,7 @@ class DBSelectWin (sg.Window): ...@@ -47,7 +58,7 @@ class DBSelectWin (sg.Window):
[ [
self.buttons["-open-close-"], self.buttons["-open-close-"],
self.buttons["-edit-"], self.buttons["-edit-"],
self.buttons["-plot-"], self.buttons["-indicators-"],
sg.Push(), sg.Push(),
self.buttons["-new-"], self.buttons["-new-"],
] ]
...@@ -63,14 +74,14 @@ class DBSelectWin (sg.Window): ...@@ -63,14 +74,14 @@ class DBSelectWin (sg.Window):
""" """
has_db = self.db is not None has_db = self.db is not None
using_data = (self.edit_window is not None) using_data = (self.edit_window is not None) or (self.indicator_popup is not None)
self.buttons["-edit-"].update( self.buttons["-edit-"].update(
disabled=not has_db or using_data, disabled=not has_db or using_data,
button_color=sg.theme_button_color() button_color=sg.theme_button_color()
) )
self.buttons["-plot-"].update( self.buttons["-indicators-"].update(
disabled=not has_db or using_data, disabled=not has_db or using_data,
button_color=sg.theme_button_color() button_color=sg.theme_button_color()
) )
...@@ -96,6 +107,15 @@ class DBSelectWin (sg.Window): ...@@ -96,6 +107,15 @@ class DBSelectWin (sg.Window):
button_color=sg.theme_button_color() button_color=sg.theme_button_color()
) )
self.indicator_popup_lock.acquire()
if self.indicator_popup is not None:
self.indicator_popup["-run-name-"].update(value=self.indicator_run_name)
self.indicator_popup["-progress-"].update(current_count=self.indicator_progress)
self.indicator_popup.read(1)
self.indicator_popup_lock.release()
def open_database (self, path: str): def open_database (self, path: str):
"""Tries to open a Database """Tries to open a Database
...@@ -154,6 +174,57 @@ class DBSelectWin (sg.Window): ...@@ -154,6 +174,57 @@ class DBSelectWin (sg.Window):
self.inputs["-db_path-"].update(value=text) self.inputs["-db_path-"].update(value=text)
self.open_database(text) self.open_database(text)
def compute_indicators (self):
self.indicator_max_progress = len(self.db.list_files()) + 1
self.indicator_progress = 0
popup = sg.Window("Computing indicators", [
[ sg.Push(), sg.Text("Computing indicators."), sg.Push() ],
[
sg.Push(),
sg.Text(
"This might take a while",
justification="center"
),
sg.Push()
],
[
sg.Push(),
sg.Text("Waiting ...", key="-run-name-"),
sg.Push()
],
[
sg.ProgressBar(self.indicator_max_progress, expand_x=True, key="-progress-")
]
], finalize=True, disable_close=True, disable_minimize=True)
popup.read(1)
self.indicator_popup = popup
self.db.close()
def compute_thread (self: DBSelectWin):
def next (name: str):
print("Next", name)
self.indicator_popup_lock.acquire()
self.indicator_run_name = name
self.indicator_progress += 1
self.indicator_popup_lock.release()
print("Released lock")
self.db.open()
compute_indicators_all_robots(self.db, next)
self.db.close()
self.indicator_popup_lock.acquire()
self.db_use_done = True
self.indicator_popup_lock.release()
Thread(target=compute_thread, daemon=True, args=[self]).start()
def poll (self): def poll (self):
"""Runs the window """Runs the window
...@@ -178,7 +249,19 @@ class DBSelectWin (sg.Window): ...@@ -178,7 +249,19 @@ class DBSelectWin (sg.Window):
self.edit_window.close() self.edit_window.close()
self.edit_window = None self.edit_window = None
self.update_display() self.update_display()
# DB management
self.indicator_popup_lock.acquire()
if self.db_use_done == True:
self.db_use_done = False
self.indicator_popup.close()
self.indicator_popup = None
self.db.open()
self.indicator_popup_lock.release()
# Update display
self.update_display()
return True return True
# User opens the Database # User opens the Database
...@@ -200,9 +283,10 @@ class DBSelectWin (sg.Window): ...@@ -200,9 +283,10 @@ class DBSelectWin (sg.Window):
self.edit_window = DBFileManagerWindow(self.db) self.edit_window = DBFileManagerWindow(self.db)
# User wants to plot some data # User wants to plot some data
if event == "-plot-": if event == "-indicators-":
pass self.compute_indicators()
# Update this window display # Update this window display
self.update_display() self.update_display()
return True return True
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment