mg-pso-gui 0.1.40__py3-none-any.whl → 0.2.75__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mg_pso_gui-0.1.40.dist-info → mg_pso_gui-0.2.75.dist-info}/METADATA +10 -11
- mg_pso_gui-0.2.75.dist-info/RECORD +76 -0
- {mg_pso_gui-0.1.40.dist-info → mg_pso_gui-0.2.75.dist-info}/WHEEL +1 -1
- mgpsogui/gui/General/ParameterView.py +110 -0
- mgpsogui/gui/General/__init__.py +0 -0
- mgpsogui/gui/HomePage.py +234 -238
- mgpsogui/gui/OptionManager.py +333 -145
- mgpsogui/gui/OptionManager_backup.py +443 -0
- mgpsogui/gui/PlatformTab/PlatformTab.py +15 -6
- mgpsogui/gui/RunTab/OptimalParameterView.py +47 -0
- mgpsogui/gui/RunTab/RunTab.py +90 -17
- mgpsogui/gui/SetupTab/BoundsEditorWindow.py +1 -1
- mgpsogui/gui/SetupTab/BoundsList.py +97 -34
- mgpsogui/gui/SetupTab/CustomFunctionEditorWindow.py +74 -0
- mgpsogui/gui/SetupTab/CustomFunctionMetrics.py +156 -0
- mgpsogui/gui/SetupTab/FunctionsList.py +60 -6
- mgpsogui/gui/SetupTab/{StaticParameterView.py → ListEditor.py} +27 -16
- mgpsogui/gui/SetupTab/ListParametersView.py +7 -6
- mgpsogui/gui/SetupTab/{CalibrationParametersView.py → OverrideParameterMetrics.py} +35 -9
- mgpsogui/gui/SetupTab/OverrideParameterWindow.py +40 -0
- mgpsogui/gui/SetupTab/SetupTab.py +31 -11
- mgpsogui/gui/SetupTab/StepView.py +93 -22
- mgpsogui/gui/VisualizeTab/MatrixEditor.py +68 -0
- mgpsogui/gui/VisualizeTab/SideBar.py +316 -25
- mgpsogui/gui/VisualizeTab/VisualizeTab.py +69 -8
- mgpsogui/gui/defaults/__init__.py +0 -0
- mgpsogui/gui/defaults/optimization.json +176 -0
- mgpsogui/gui/defaults/sampling.json +111 -0
- mgpsogui/gui/defaults/sensitivity.json +20 -0
- mgpsogui/gui/images/plus.png +0 -0
- mgpsogui/util/GraphGenerator.py +721 -50
- mgpsogui/util/PSORunner.py +615 -86
- mgpsogui/util/debug.py +559 -0
- mgpsogui/util/helpers.py +95 -0
- mgpsogui/util/recosu/__init__.py +2 -1
- mgpsogui/util/recosu/pso/pso.py +55 -11
- mgpsogui/util/recosu/sampling/__init__.py +16 -0
- mgpsogui/util/recosu/sampling/halton/__init__.py +0 -0
- mgpsogui/util/recosu/sampling/halton/halton.py +45 -0
- mgpsogui/util/recosu/sampling/halton/prime.py +82 -0
- mgpsogui/util/recosu/sampling/random/__init__.py +0 -0
- mgpsogui/util/recosu/sampling/random/random_sampler.py +34 -0
- mgpsogui/util/recosu/sampling/sample_trace_writer.py +47 -0
- mgpsogui/util/recosu/sampling/sampler_task.py +75 -0
- mgpsogui/util/recosu/sampling/sampling.py +99 -0
- mgpsogui/util/sampler_test_driver.py +129 -0
- mg_pso_gui-0.1.40.dist-info/RECORD +0 -52
- mgpsogui/gui/images/IGOW 4 Logo.png +0 -0
- {mg_pso_gui-0.1.40.dist-info → mg_pso_gui-0.2.75.dist-info}/entry_points.txt +0 -0
- {mg_pso_gui-0.1.40.dist-info → mg_pso_gui-0.2.75.dist-info}/top_level.txt +0 -0
mgpsogui/gui/HomePage.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#!/usr/local/bin/python3.
|
1
|
+
#!/usr/local/bin/python3.10
|
2
2
|
|
3
3
|
import os
|
4
4
|
import time
|
@@ -13,12 +13,14 @@ import requests
|
|
13
13
|
import tkinter as tk
|
14
14
|
import tkinter.messagebox
|
15
15
|
import customtkinter
|
16
|
+
from customtkinter import ThemeManager
|
16
17
|
import json
|
17
18
|
import os
|
18
19
|
from PIL import Image, ImageTk
|
19
20
|
import traceback
|
20
21
|
from multiprocessing import Process
|
21
22
|
from multiprocessing import Queue
|
23
|
+
|
22
24
|
import re
|
23
25
|
import pandas as pd
|
24
26
|
import numpy as np
|
@@ -31,6 +33,7 @@ from queue import Empty
|
|
31
33
|
from ..util import PSORunner
|
32
34
|
from ..util import GraphGenerator
|
33
35
|
from ..util.CTkToolTip import CTkToolTip as ctt
|
36
|
+
from ..util import helpers as hp
|
34
37
|
|
35
38
|
import subprocess
|
36
39
|
import plotly.express as px
|
@@ -48,13 +51,12 @@ from .VisualizeTab import VisualizeTab as vt
|
|
48
51
|
|
49
52
|
from ..util.CTkToolTip import CTkToolTip as ctt
|
50
53
|
|
51
|
-
customtkinter.set_appearance_mode("
|
54
|
+
customtkinter.set_appearance_mode("System") # Modes: "System" (standard), "Dark", "Light"
|
52
55
|
customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue"
|
53
56
|
|
54
57
|
results_queue = Queue()
|
55
58
|
stdout_queue = Queue()
|
56
59
|
stderr_queue = Queue()
|
57
|
-
cosu_queue = Queue()
|
58
60
|
|
59
61
|
class App(customtkinter.CTk):
|
60
62
|
def __init__(self):
|
@@ -62,22 +64,37 @@ class App(customtkinter.CTk):
|
|
62
64
|
|
63
65
|
self.option_manager = om.OptionManager()
|
64
66
|
|
65
|
-
self.graph_selector_value = tk.StringVar()
|
66
|
-
self.graph_selector_value.set("Best Cost Stacked")
|
67
|
+
# self.graph_selector_value = tk.StringVar()
|
68
|
+
# self.graph_selector_value.set("Best Cost Stacked")
|
69
|
+
|
70
|
+
# self.graph_theme_value = tk.StringVar()
|
71
|
+
# self.graph_theme_value.set("Dark")
|
67
72
|
|
68
|
-
self.selected_csv = tk.StringVar()
|
69
|
-
self.selected_csv.set("No files found...")
|
73
|
+
# self.selected_csv = tk.StringVar()
|
74
|
+
# self.selected_csv.set("No files found...")
|
70
75
|
self.open_file = "None"
|
71
76
|
self.csv_data = None
|
72
77
|
|
73
|
-
self.
|
74
|
-
self.
|
78
|
+
# self.selected_csv2 = tk.StringVar()
|
79
|
+
# self.selected_csv2.set("No files found...")
|
80
|
+
self.open_file2 = "None"
|
81
|
+
self.csv_data2 = None
|
82
|
+
|
83
|
+
# self.selected_x = tk.StringVar()
|
84
|
+
# self.selected_x.set("time")
|
75
85
|
|
76
|
-
self.selected_y1 = tk.StringVar()
|
77
|
-
self.selected_y1.set("NONE")
|
86
|
+
# self.selected_y1 = tk.StringVar()
|
87
|
+
# self.selected_y1.set("NONE")
|
78
88
|
|
79
|
-
self.selected_y2 = tk.StringVar()
|
80
|
-
self.selected_y2.set("NONE")
|
89
|
+
# self.selected_y2 = tk.StringVar()
|
90
|
+
# self.selected_y2.set("NONE")
|
91
|
+
|
92
|
+
# self.figure_style = tk.StringVar()
|
93
|
+
# self.figure_style.set("Scatter")
|
94
|
+
|
95
|
+
# self.matrix_values = []
|
96
|
+
# self.matrix_values.append(tk.StringVar())
|
97
|
+
# self.matrix_values[0].set("NONE")
|
81
98
|
|
82
99
|
self.running_config = None
|
83
100
|
self.selected_graph_name = None
|
@@ -92,9 +109,10 @@ class App(customtkinter.CTk):
|
|
92
109
|
self.image_height = 720
|
93
110
|
self.progress_data = None
|
94
111
|
self.calibration_data = None
|
112
|
+
self.testing = False
|
95
113
|
|
96
114
|
# configure window
|
97
|
-
self.title("
|
115
|
+
self.title("COSU Manager")
|
98
116
|
self.geometry(f"{1920}x{1080}")
|
99
117
|
|
100
118
|
# configure grid layout (4x4)
|
@@ -107,7 +125,7 @@ class App(customtkinter.CTk):
|
|
107
125
|
self.sidebar_frame = customtkinter.CTkFrame(self, width=140, corner_radius=0)
|
108
126
|
self.sidebar_frame.grid(row=0, column=0, sticky="nsew")
|
109
127
|
self.sidebar_frame.grid_columnconfigure(4, weight=1)
|
110
|
-
self.logo_label = customtkinter.CTkLabel(self.sidebar_frame, text="
|
128
|
+
self.logo_label = customtkinter.CTkLabel(self.sidebar_frame, text="COSU Manager", font=customtkinter.CTkFont(size=20, weight="bold"))
|
111
129
|
self.logo_label.grid(row=0, column=0, padx=(20, 10), pady=header_padding_y)
|
112
130
|
self.save_button = customtkinter.CTkButton(self.sidebar_frame, text="Save", width=60, command=self.save_project)
|
113
131
|
self.save_button.grid(row=0, column=1, padx=header_padding_x, pady=header_padding_y)
|
@@ -117,40 +135,39 @@ class App(customtkinter.CTk):
|
|
117
135
|
# 4 is service URL
|
118
136
|
self.service_label = customtkinter.CTkLabel(self.sidebar_frame, text="Service:", anchor="w")
|
119
137
|
self.service_label.grid(row=0, column=3, padx=(80, 5), pady=header_padding_y)
|
120
|
-
self.service_url = customtkinter.CTkEntry(self.sidebar_frame, textvariable=self.option_manager.
|
138
|
+
self.service_url = customtkinter.CTkEntry(self.sidebar_frame, textvariable=self.option_manager.get("url"))
|
121
139
|
self.service_url.grid(row=0, column=4, columnspan=1, padx=header_padding_x, pady=header_padding_y, sticky="nsew")
|
122
140
|
refresh_image = customtkinter.CTkImage(Image.open(os.path.join("./images", "refresh.png")), size=(20, 20))
|
123
141
|
self.refresh_button = customtkinter.CTkButton(self.sidebar_frame, text=None, width=30, image=refresh_image, command=self.load)
|
124
142
|
ctt(self.refresh_button, delay=0.1, alpha=0.95, message="Connect to Service")
|
125
|
-
self.refresh_button.grid(row=0, column=5, padx=
|
143
|
+
self.refresh_button.grid(row=0, column=5, padx=header_padding_x, pady=header_padding_y)
|
144
|
+
|
145
|
+
self.algorithm_optionmenu = customtkinter.CTkOptionMenu(self.sidebar_frame, variable=self.option_manager.get_mode_sv(), values=self.option_manager.get_service_modes(), width=50, command=self.refresh_step_view)
|
146
|
+
self.algorithm_optionmenu.grid(row=0, column=6, padx=(5, 80), pady=header_padding_y)
|
126
147
|
|
127
148
|
self.scaling_label = customtkinter.CTkLabel(self.sidebar_frame, text="Scale:", anchor="w")
|
128
|
-
self.scaling_label.grid(row=0, column=
|
149
|
+
self.scaling_label.grid(row=0, column=7, padx=header_padding_x, pady=header_padding_y)
|
129
150
|
self.scaling_optionemenu = customtkinter.CTkOptionMenu(self.sidebar_frame, values=["50%", "75%", "100%", "125%", "150%", "175%", "200%"], width=60,
|
130
|
-
|
131
|
-
self.scaling_optionemenu.grid(row=0, column=
|
151
|
+
command=self.change_scaling_event)
|
152
|
+
self.scaling_optionemenu.grid(row=0, column=8, padx=(5, 20), pady=header_padding_y)
|
132
153
|
self.scaling_optionemenu.set("100%")
|
133
154
|
|
134
155
|
expand_image = customtkinter.CTkImage(Image.open(os.path.join("./images", "expand.png")), size=(20, 20))
|
135
|
-
self.new_window = customtkinter.CTkButton(self.sidebar_frame, text=None, width=30, image=expand_image, command=self.
|
136
|
-
ctt(self.new_window, delay=0.1, alpha=0.95, message="Open New Window")
|
137
|
-
self.new_window.grid(row=0, column=
|
156
|
+
#self.new_window = customtkinter.CTkButton(self.sidebar_frame, text=None, width=30, image=expand_image, command=self.open_new_window)
|
157
|
+
#ctt(self.new_window, delay=0.1, alpha=0.95, message="Open New Window")
|
158
|
+
#self.new_window.grid(row=0, column=9, padx=(5, 20), pady=header_padding_y)
|
138
159
|
|
139
160
|
self.tabview = customtkinter.CTkTabview(self, bg_color="transparent", fg_color="transparent")
|
140
161
|
self.tabview.grid(row=1, column=0, padx=(0, 0), pady=(10, 10), sticky="nsew")
|
141
162
|
tab1 = "Platform"
|
142
163
|
tab2 = "Setup"
|
143
|
-
tab3 = "
|
164
|
+
tab3 = "Project"
|
144
165
|
tab4 = "Results"
|
145
|
-
#tab5 = "Results"
|
146
166
|
|
147
167
|
self.tabview.add(tab1)
|
148
168
|
self.tabview.add(tab2)
|
149
169
|
self.tabview.add(tab4)
|
150
170
|
self.tabview.add(tab3)
|
151
|
-
#self.tabview.add(tab5)
|
152
|
-
|
153
|
-
#self.tabview.configure(state="disabled")
|
154
171
|
|
155
172
|
pt.create_tab(self, self.tabview.tab(tab1))
|
156
173
|
st.create_tab(self, self.tabview.tab(tab2))
|
@@ -167,18 +184,14 @@ class App(customtkinter.CTk):
|
|
167
184
|
self.footer_progress_bar = customtkinter.CTkProgressBar(self.footer_frame)
|
168
185
|
self.footer_progress_bar.grid(row=0, column=4, padx=(50, 100), pady=header_padding_y, sticky="ew")
|
169
186
|
self.footer_progress_bar.set(0)
|
170
|
-
|
171
|
-
self.algorithm_optionmenu = customtkinter.CTkOptionMenu(self.footer_frame, values=["PSO", "Halton"], width=50)
|
172
|
-
self.algorithm_optionmenu.grid(row=0, column=6, padx=header_padding_x, pady=header_padding_y)
|
173
|
-
self.algorithm_optionmenu.set("PSO")
|
174
187
|
|
175
188
|
play_image = customtkinter.CTkImage(Image.open(os.path.join("./images", "play.png")), size=(20, 20))
|
176
189
|
self.run_button = customtkinter.CTkButton(self.footer_frame, text=None, width=30, image=play_image, command=self.run)
|
177
|
-
ctt(self.run_button, delay=0.1, alpha=0.95, message="Start
|
190
|
+
ctt(self.run_button, delay=0.1, alpha=0.95, message="Start Job")
|
178
191
|
self.run_button.grid(row=0, column=7, padx=(20, 5), pady=header_padding_y)
|
179
192
|
|
180
193
|
test_image = customtkinter.CTkImage(Image.open(os.path.join("./images", "test.png")), size=(20, 20))
|
181
|
-
self.test_button = customtkinter.CTkButton(self.footer_frame, text=None, width=30, image=test_image, command=self.
|
194
|
+
self.test_button = customtkinter.CTkButton(self.footer_frame, text=None, width=30, image=test_image, command=self.run_test)
|
182
195
|
ctt(self.test_button, delay=0.1, alpha=0.95, message="Start Testing")
|
183
196
|
self.test_button.grid(row=0, column=8, padx=(5, 5), pady=header_padding_y)
|
184
197
|
|
@@ -192,74 +205,26 @@ class App(customtkinter.CTk):
|
|
192
205
|
ctt(self.download_button, delay=0.1, alpha=0.95, message="Download Results")
|
193
206
|
self.download_button.grid(row=0, column=10, padx=(5, 20), pady=header_padding_y)
|
194
207
|
|
208
|
+
self.refresh_step_view(0)
|
195
209
|
self.after(1000, self.running_loop)
|
196
210
|
|
197
211
|
def update_graph(self, value):
|
198
212
|
self.vis_sidebar.refresh()
|
199
213
|
GraphGenerator.generate_graphs(self)
|
200
|
-
|
201
|
-
'''def _resize_image(self, event):
|
202
|
-
self.graph_label.update_idletasks()
|
203
|
-
new_width = self.graph_label.winfo_width()
|
204
|
-
new_height = self.graph_label.winfo_height()
|
205
|
-
|
206
|
-
alt_width = new_height * 1.77778
|
207
|
-
alt_height = new_width / 1.77778
|
208
|
-
|
209
|
-
if (new_width < new_height):
|
210
|
-
new_height = alt_height
|
211
|
-
else:
|
212
|
-
new_width = alt_width
|
213
|
-
|
214
|
-
self.image_width = new_width
|
215
|
-
self.image_height = new_height
|
216
|
-
|
217
|
-
self.graph_image = customtkinter.CTkImage(self.graph_image_obj, size=(new_width, new_height))
|
218
|
-
self.graph_label.configure(image=self.graph_image)
|
219
|
-
self.graph_label.update_idletasks()
|
220
|
-
|
221
|
-
|
222
|
-
def update_graph(self, value):
|
223
|
-
selected_graph = self.graph_selector_value.get()
|
224
|
-
info = self.option_manager.get_project_data()
|
225
|
-
folder = os.path.join(info['path'], info['name'])
|
226
|
-
|
227
|
-
if not os.path.exists(folder):
|
228
|
-
os.makedirs(folder)
|
229
|
-
|
230
|
-
if (selected_graph == "Best Cost Stacked"):
|
231
|
-
self.selected_graph_name = "best_cost_stacked"
|
232
|
-
elif (selected_graph == "Best Cost by Round"):
|
233
|
-
self.selected_graph_name = "best_cost_by_round"
|
234
|
-
elif (selected_graph == "Iteration Table"):
|
235
|
-
self.selected_graph_name = "table"
|
236
|
-
elif (selected_graph == "Calibrated Parameters"):
|
237
|
-
self.selected_graph_name = "calibrated_params_by_round"
|
238
|
-
|
239
|
-
image_path = os.path.join(folder, self.selected_graph_name + ".png")
|
240
|
-
if not os.path.exists(image_path):
|
241
|
-
image_path = os.path.join("./images", "up.png")
|
242
|
-
self.graph_image_obj = Image.open(image_path)
|
243
|
-
self.graph_image = customtkinter.CTkImage(self.graph_image_obj, size=(self.image_width * self.image_scale, self.image_height * self.image_scale))
|
244
|
-
self.graph_label.configure(image=self.graph_image)'''
|
245
214
|
|
246
215
|
def save_project(self):
|
247
|
-
metrics = self.option_manager.get_metrics()
|
248
|
-
|
249
|
-
# Add the calibration_progress dataframe to the json
|
250
|
-
if (self.progress_data is not None):
|
251
|
-
metrics["calibration_progress"] = self.progress_data.to_json()
|
252
|
-
# Add the calibration_data to the json
|
253
|
-
if (self.calibration_data is not None):
|
254
|
-
metrics["calibration_data"] = self.calibration_data
|
255
|
-
|
256
216
|
filename = asksaveasfilename(filetypes=[("JSON", "*.json")], initialfile="config", defaultextension="json", title="Save Project")
|
257
217
|
|
258
218
|
try:
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
219
|
+
self.option_manager.set_path(filename)
|
220
|
+
self.option_manager.save_project(filename)
|
221
|
+
|
222
|
+
folder = self.option_manager.get_project_folder()
|
223
|
+
if not os.path.exists(folder):
|
224
|
+
os.makedirs(folder)
|
225
|
+
|
226
|
+
if not os.path.exists(os.path.join(folder, "results")):
|
227
|
+
os.makedirs(os.path.join(folder, "results"))
|
263
228
|
|
264
229
|
self.save_button.configure(text="Saved!")
|
265
230
|
self.after(3000, lambda: self.save_button.configure(text="Save"))
|
@@ -268,7 +233,59 @@ class App(customtkinter.CTk):
|
|
268
233
|
print(e)
|
269
234
|
self.after(3000, lambda: self.save_button.configure(text="Save"))
|
270
235
|
|
271
|
-
def
|
236
|
+
def refresh_step_view(self, value):
|
237
|
+
mode = self.option_manager.get_mode()
|
238
|
+
self.service_url.configure(textvariable=self.option_manager.get("url"))
|
239
|
+
self.graph_theme.configure(variable=self.option_manager.get("graph_theme"))
|
240
|
+
|
241
|
+
# Limit graph selection based on mode
|
242
|
+
self.graph_selector.configure(variable=self.option_manager.get("selected_graph"))
|
243
|
+
graph_types = []
|
244
|
+
if mode == "Optimization":
|
245
|
+
graph_types = ["Best Cost Stacked", "Best Cost by Round", "Custom CSV", "Compare CSV"]
|
246
|
+
elif mode == "Sensitivity Analysis":
|
247
|
+
graph_types = ["Custom CSV", "Compare CSV"]
|
248
|
+
elif mode == "Sampling: Halton" or mode == "Sampling Random":
|
249
|
+
graph_types = ["Sampling CSV", "Matrix Editor"]
|
250
|
+
self.graph_selector.configure(values=graph_types)
|
251
|
+
selected_graph = self.option_manager.get("selected_graph").get()
|
252
|
+
if selected_graph not in graph_types:
|
253
|
+
self.option_manager.get("selected_graph").set(graph_types[0])
|
254
|
+
|
255
|
+
|
256
|
+
if mode == "Optimization":
|
257
|
+
self.test_button.configure(state="normal")
|
258
|
+
self.test_button.configure(fg_color=get_color("CTkButton"))
|
259
|
+
self.download_button.configure(state="normal")
|
260
|
+
self.download_button.configure(fg_color=get_color("CTkButton"))
|
261
|
+
else:
|
262
|
+
self.test_button.configure(state="disabled")
|
263
|
+
self.test_button.configure(fg_color="gray")
|
264
|
+
self.download_button.configure(state="disabled")
|
265
|
+
self.download_button.configure(fg_color="gray")
|
266
|
+
|
267
|
+
self.vis_sidebar.clear()
|
268
|
+
self.vis_sidebar.render()
|
269
|
+
|
270
|
+
self.steps_frame.clear()
|
271
|
+
self.steps_frame.render()
|
272
|
+
|
273
|
+
self.static_param_frame.clear()
|
274
|
+
self.static_param_frame.render()
|
275
|
+
|
276
|
+
self.calib_param_frame.clear()
|
277
|
+
self.calib_param_frame.render()
|
278
|
+
|
279
|
+
self.service_param_frame.clear()
|
280
|
+
self.service_param_frame.render()
|
281
|
+
|
282
|
+
self.optimal_param_frame.clear()
|
283
|
+
self.optimal_param_frame.render()
|
284
|
+
|
285
|
+
self.project_name_label.configure(text=self.option_manager.get_project_data()["name"])
|
286
|
+
self.project_path_label.configure(text=self.option_manager.get_project_data()["path"])
|
287
|
+
|
288
|
+
def open_new_window(self):
|
272
289
|
# Shell out and run ./main.py
|
273
290
|
subprocess.Popen(["python3", "../mgpsogui.py"])
|
274
291
|
|
@@ -279,53 +296,29 @@ class App(customtkinter.CTk):
|
|
279
296
|
|
280
297
|
try:
|
281
298
|
|
282
|
-
|
283
|
-
with open(filename, "r") as f:
|
284
|
-
metrics = json.loads(f.read())
|
285
|
-
|
299
|
+
self.option_manager.load_project(filename)
|
286
300
|
self.option_manager.set_path(filename)
|
287
|
-
|
288
|
-
if "arguments" in metrics:
|
289
|
-
metrics["arguments"]["calibration_parameters"] = metrics["calibration_parameters"]
|
290
|
-
|
291
|
-
if "service_parameters" in metrics:
|
292
|
-
self.option_manager.set_service_parameters(metrics["service_parameters"])
|
293
|
-
self.tabview.configure(state="enabled")
|
294
|
-
|
295
|
-
if "calibration_progress" in metrics:
|
296
|
-
self.progress_data = pd.read_json(metrics["calibration_progress"])
|
297
|
-
self.calibration_data = metrics["calibration_data"]
|
298
|
-
print(self.progress_data)
|
299
|
-
|
300
|
-
if "calibration_data" in metrics:
|
301
|
-
self.calibration_data = metrics["calibration_data"]
|
302
|
-
print(self.calibration_data)
|
303
|
-
|
304
|
-
print(metrics)
|
305
|
-
|
306
|
-
self.option_manager.clear()
|
307
|
-
self.option_manager.add_arguments(metrics["arguments"])
|
308
|
-
self.option_manager.add_steps(metrics["steps"])
|
309
|
-
|
310
|
-
self.steps_frame.clear()
|
311
|
-
self.steps_frame.render()
|
312
301
|
|
313
|
-
self.
|
314
|
-
|
302
|
+
folder = self.option_manager.get_project_folder()
|
303
|
+
if not os.path.exists(folder):
|
304
|
+
os.makedirs(folder)
|
305
|
+
|
306
|
+
if not os.path.exists(os.path.join(folder, "results")):
|
307
|
+
os.makedirs(os.path.join(folder, "results"))
|
315
308
|
|
316
|
-
self.
|
317
|
-
self.calib_param_frame.render()
|
318
|
-
|
319
|
-
info = self.option_manager.get_project_data()
|
320
|
-
folder = os.path.join(info['path'], info['name'])
|
321
|
-
self.HRU_data = pd.read_csv(os.path.join(folder, "results", "HRU_1.csv"), skiprows=3)
|
322
|
-
print(self.HRU_data)
|
309
|
+
self.refresh_step_view(0)
|
323
310
|
|
324
311
|
self.load_button.configure(text="Loaded!")
|
325
312
|
self.after(3000, lambda: self.load_button.configure(text="Load"))
|
313
|
+
|
314
|
+
self.load()
|
326
315
|
|
327
316
|
except Exception as e:
|
328
317
|
print(e)
|
318
|
+
# Print stack trace
|
319
|
+
traceback.print_exc()
|
320
|
+
|
321
|
+
|
329
322
|
self.load_button.configure(text="Error!")
|
330
323
|
self.after(3000, lambda: self.load_button.configure(text="Load"))
|
331
324
|
|
@@ -343,12 +336,12 @@ class App(customtkinter.CTk):
|
|
343
336
|
def make_request(self):
|
344
337
|
service_url = self.service_url.get()
|
345
338
|
try:
|
346
|
-
response = requests.get(service_url)
|
339
|
+
response = requests.get(service_url, timeout=5)
|
347
340
|
|
348
341
|
response_json = json.loads(response.text)
|
349
342
|
status = response.status_code
|
350
343
|
|
351
|
-
self.option_manager.
|
344
|
+
self.option_manager.set_data("service_request_data", response_json)
|
352
345
|
|
353
346
|
self.service_status.delete('0.0', tk.END)
|
354
347
|
self.service_status.insert(text=str(status), index='0.0')
|
@@ -358,29 +351,45 @@ class App(customtkinter.CTk):
|
|
358
351
|
self.service_description.insert(text=str(response_json["metainfo"]["description"]), index='0.0')
|
359
352
|
self.service_details.delete('0.0', tk.END)
|
360
353
|
self.service_details.insert(text=json.dumps(response_json, indent=4), index='0.0')
|
361
|
-
|
354
|
+
|
362
355
|
self.refresh_button.configure(fg_color="green")
|
363
356
|
except Exception as e:
|
364
357
|
self.refresh_button.configure(fg_color="red")
|
358
|
+
self.after(1000, lambda: self.refresh_button.configure(fg_color=get_color("CTkButton")))
|
359
|
+
|
360
|
+
self.refresh_step_view(0)
|
365
361
|
|
366
362
|
|
367
363
|
def load(self):
|
368
364
|
# Make HTTP request to service_url and save the result to bounds.json
|
369
365
|
|
370
|
-
self.default_button_color = self.refresh_button.cget("fg_color")
|
371
|
-
|
372
366
|
self.refresh_button.configure(fg_color="gray")
|
373
367
|
|
374
368
|
self.after(10, self.make_request)
|
375
|
-
self.after(3000, lambda: self.refresh_button.configure(fg_color=
|
369
|
+
self.after(3000, lambda: self.refresh_button.configure(fg_color=get_color("CTkButton")))
|
376
370
|
|
371
|
+
def run_test(self):
|
372
|
+
self.testing = True
|
373
|
+
self.run()
|
374
|
+
|
377
375
|
def run(self):
|
378
|
-
metrics = self.option_manager.get_metrics()
|
379
|
-
self.running_config = metrics
|
380
376
|
|
377
|
+
data = self.option_manager.get_all_data()
|
378
|
+
mode = self.option_manager.get_mode()
|
379
|
+
data = data[mode]
|
380
|
+
|
381
|
+
self.running_config = data
|
382
|
+
|
383
|
+
#if self.testing:
|
384
|
+
# steps = metrics['steps']
|
385
|
+
# for step in steps:
|
386
|
+
# for param in step['param']:
|
387
|
+
# param['default_value'] = param['optimal_value']
|
388
|
+
self.testing = False
|
389
|
+
|
381
390
|
self.progress_data = None
|
382
391
|
self.calibration_data = None
|
383
|
-
|
392
|
+
|
384
393
|
#self.progress_bar.configure(mode="indeterminnate")
|
385
394
|
#self.progress_bar.start()
|
386
395
|
self.footer_progress_bar.configure(mode="indeterminnate")
|
@@ -389,26 +398,16 @@ class App(customtkinter.CTk):
|
|
389
398
|
self.data_x = [0]
|
390
399
|
self.data_y = [0]
|
391
400
|
|
392
|
-
self.progress_message_middle.configure(text="
|
401
|
+
#self.progress_message_middle.configure(text="Job starting...")
|
393
402
|
self.footer_progress_label.configure(text="Starting...")
|
394
403
|
|
395
|
-
self.textbox.insert("0.0", "Starting
|
396
|
-
self.textbox.insert("0.0", "
|
397
|
-
self.textbox.insert("0.0", json.dumps(
|
404
|
+
self.textbox.insert("0.0", "Starting job...\n\n")
|
405
|
+
self.textbox.insert("0.0", "Job Parameters:\n")
|
406
|
+
self.textbox.insert("0.0", json.dumps(data, indent=4) + "\n\n")
|
398
407
|
try:
|
399
|
-
|
400
|
-
folder = os.path.join(info['path'], info['name'])
|
401
|
-
|
402
|
-
if not os.path.exists(folder):
|
403
|
-
os.makedirs(folder)
|
404
|
-
|
405
|
-
if (os.path.exists(os.path.join(folder, 'output.txt'))):
|
406
|
-
os.remove(os.path.join(folder, 'output.txt'))
|
407
|
-
|
408
|
-
if (os.path.exists(os.path.join(folder, 'error.txt'))):
|
409
|
-
os.remove(os.path.join(folder, 'error.txt'))
|
408
|
+
folder = self.option_manager.get_project_folder()
|
410
409
|
|
411
|
-
self.train_process = Process(target=PSORunner.run_process, args=(stdout_queue, stderr_queue, results_queue,
|
410
|
+
self.train_process = Process(target=PSORunner.run_process, args=(stdout_queue, stderr_queue, results_queue, data, folder, mode))
|
412
411
|
self.train_process.daemon = True
|
413
412
|
self.train_process.start()
|
414
413
|
self.after(1000, self.watch_loop)
|
@@ -420,10 +419,10 @@ class App(customtkinter.CTk):
|
|
420
419
|
self.textbox.insert("0.0", "Stack trace:\n")
|
421
420
|
self.textbox.insert("0.0", traceback.format_exc())
|
422
421
|
self.textbox.insert("0.0", "\n\n")
|
423
|
-
self.textbox.insert("0.0", "
|
424
|
-
self.progress_message_left.configure(text="")
|
425
|
-
self.progress_message_middle.configure(text="
|
426
|
-
self.progress_message_right.configure(text="")
|
422
|
+
self.textbox.insert("0.0", "Job failed!")
|
423
|
+
#self.progress_message_left.configure(text="")
|
424
|
+
#self.progress_message_middle.configure(text="Job failed! See error log below.")
|
425
|
+
#self.progress_message_right.configure(text="")
|
427
426
|
self.footer_progress_label.configure(text="Failed")
|
428
427
|
#self.progress_bar.stop()
|
429
428
|
self.footer_progress_bar.stop()
|
@@ -431,35 +430,35 @@ class App(customtkinter.CTk):
|
|
431
430
|
self.footer_progress_bar.configure(mode="determinate")
|
432
431
|
#self.progress_bar.set(0)
|
433
432
|
self.footer_progress_bar.set(0)
|
433
|
+
|
434
434
|
|
435
435
|
def stop(self):
|
436
436
|
print("Stopping...")
|
437
437
|
self.train_process.terminate()
|
438
438
|
|
439
|
-
|
440
|
-
folder = os.path.join(info['path'], info['name'])
|
439
|
+
folder = self.option_manager.get_project_folder()
|
441
440
|
|
442
441
|
if not os.path.exists(folder):
|
443
442
|
os.makedirs(folder)
|
444
443
|
|
445
444
|
# Stop the process
|
446
|
-
if (os.path.exists(os.path.join(folder, 'output.txt'))):
|
447
|
-
|
445
|
+
#if (os.path.exists(os.path.join(folder, 'output.txt'))):
|
446
|
+
# os.remove(os.path.join(folder, 'output.txt'))
|
448
447
|
|
449
|
-
if (os.path.exists(os.path.join(folder, 'error.txt'))):
|
450
|
-
|
448
|
+
#if (os.path.exists(os.path.join(folder, 'error.txt'))):
|
449
|
+
# os.remove(os.path.join(folder, 'error.txt'))
|
451
450
|
|
452
|
-
self.textbox.insert("0.0", "
|
451
|
+
self.textbox.insert("0.0", "Job terminated!\n")
|
453
452
|
#self.progress_bar.stop()
|
454
453
|
self.footer_progress_bar.stop()
|
455
454
|
#self.progress_bar.configure(mode="determinate")
|
456
455
|
self.footer_progress_bar.configure(mode="determinate")
|
457
456
|
#self.progress_bar.set(0)
|
458
457
|
self.footer_progress_bar.set(0)
|
459
|
-
self.progress_message_left.configure(text="")
|
460
|
-
self.progress_message_middle.configure(text="
|
458
|
+
#self.progress_message_left.configure(text="")
|
459
|
+
#self.progress_message_middle.configure(text="Job stopped!")
|
461
460
|
self.footer_progress_label.configure(text="Stopped")
|
462
|
-
self.progress_message_right.configure(text="")
|
461
|
+
#self.progress_message_right.configure(text="")
|
463
462
|
|
464
463
|
def running_loop(self):
|
465
464
|
try:
|
@@ -470,9 +469,9 @@ class App(customtkinter.CTk):
|
|
470
469
|
self.after(1000, self.running_loop)
|
471
470
|
|
472
471
|
def watch_loop(self):
|
473
|
-
|
474
|
-
|
475
|
-
folder =
|
472
|
+
print("Watch loop running...")
|
473
|
+
|
474
|
+
folder = self.option_manager.get_project_folder()
|
476
475
|
|
477
476
|
if not os.path.exists(folder):
|
478
477
|
os.makedirs(folder)
|
@@ -484,29 +483,47 @@ class App(customtkinter.CTk):
|
|
484
483
|
print("# " + stdout_line, flush=True)
|
485
484
|
with open(os.path.join(folder, 'output.txt'), 'a') as f:
|
486
485
|
f.write(stdout_line)
|
487
|
-
|
488
486
|
except Empty:
|
489
487
|
break
|
490
488
|
|
491
489
|
while True:
|
492
490
|
try:
|
493
491
|
stderr_line = stderr_queue.get_nowait()
|
494
|
-
|
495
492
|
print("? " + stderr_line, flush=True)
|
496
493
|
with open(os.path.join(folder, 'error.txt'), 'a') as f:
|
497
494
|
f.write(stderr_line)
|
498
495
|
|
499
496
|
except Empty:
|
500
497
|
break
|
501
|
-
|
498
|
+
|
502
499
|
while True:
|
503
500
|
try:
|
504
|
-
|
501
|
+
trace = results_queue.get_nowait()
|
505
502
|
|
506
|
-
print("
|
503
|
+
print("TRACE " + str(trace), flush=True)
|
504
|
+
|
505
|
+
final_results = hp.extract_final_round_values(trace)
|
506
|
+
print("Final results: " + str(final_results), flush=True)
|
507
|
+
|
508
|
+
all_steps = self.option_manager.get_steps()
|
509
|
+
data = final_results["data"]
|
510
|
+
index = 0
|
511
|
+
for step in data:
|
512
|
+
for param in step.keys():
|
513
|
+
value = step[param]
|
514
|
+
target_step = all_steps[index]
|
515
|
+
for target_param in target_step['parameter_objects']:
|
516
|
+
if target_param['name'].get() == param:
|
517
|
+
target_param['optimal_value'].set(value)
|
518
|
+
index += 1
|
519
|
+
print("Applied optimal values")
|
507
520
|
except Empty:
|
508
521
|
break
|
522
|
+
except Exception as e:
|
523
|
+
print("Some error happened when getting the trace!")
|
524
|
+
print(e)
|
509
525
|
|
526
|
+
# Write output to textbox
|
510
527
|
if (os.path.exists(os.path.join(folder, 'output.txt'))):
|
511
528
|
with open(os.path.join(folder, 'output.txt'), 'r') as f:
|
512
529
|
lines = f.readlines()
|
@@ -519,6 +536,7 @@ class App(customtkinter.CTk):
|
|
519
536
|
print(new_characters, end="")
|
520
537
|
|
521
538
|
try:
|
539
|
+
# REPLACE THIS WITH READING THE STEP TRACE JSON for PSO
|
522
540
|
with open(os.path.join(folder, "output.txt"), "r") as f:
|
523
541
|
text = f.read()
|
524
542
|
|
@@ -540,65 +558,31 @@ class App(customtkinter.CTk):
|
|
540
558
|
calibrated_params = [ast.literal_eval(i) for i in calibrated_params]
|
541
559
|
best_particle_values = [ast.literal_eval(i) for i in best_particle_values]
|
542
560
|
progress_values = [tuple(map(float, i)) for i in progress_values]
|
543
|
-
|
544
|
-
#print("Current params: " + str(calibrated_params), flush=True)
|
545
|
-
|
546
561
|
self.calibration_data = calibrated_params
|
547
562
|
|
548
|
-
#GraphGenerator.calibrated_params_by_round(self.running_config['steps'], calibrated_params, self.option_manager)
|
549
|
-
#self.update_graph("")
|
550
563
|
except Exception as e:
|
551
|
-
# Print stack trace
|
552
564
|
traceback.print_exc()
|
553
|
-
|
554
565
|
print(e)
|
555
566
|
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
match = matches[-1]
|
577
|
-
percent = int(match[0])
|
578
|
-
completed_rounds = int(match[1])
|
579
|
-
total_rounds = int(match[2])
|
580
|
-
best_cost = float(match[3]) if match[3] else None
|
581
|
-
|
582
|
-
if (percent > 0):
|
583
|
-
#self.progress_bar.stop()
|
584
|
-
self.footer_progress_bar.stop()
|
585
|
-
#self.progress_bar.configure(mode="determinate")
|
586
|
-
self.footer_progress_bar.configure(mode="determinate")
|
587
|
-
#self.progress_bar.set(percent/100)
|
588
|
-
self.footer_progress_bar.set(percent/100)
|
589
|
-
self.progress_message_left.configure(text="Percent Complete: " + str(percent) + "%")
|
590
|
-
self.progress_message_middle.configure(text=str(completed_rounds) + "/" + str(total_rounds))
|
591
|
-
self.footer_progress_label.configure(text=str(completed_rounds) + "/" + str(total_rounds))
|
592
|
-
self.progress_message_right.configure(text="Best Cost: " + str(best_cost))
|
593
|
-
else:
|
594
|
-
#self.progress_bar.configure(mode="indeterminate")
|
595
|
-
self.footer_progress_bar.configure(mode="indeterminate")
|
596
|
-
#self.progress_bar.start()
|
597
|
-
self.footer_progress_bar.start()
|
598
|
-
self.progress_message_left.configure(text="")
|
599
|
-
self.progress_message_middle.configure(text="Starting new round...")
|
600
|
-
self.footer_progress_label.configure(text="Next round...")
|
601
|
-
self.progress_message_right.configure(text="")
|
567
|
+
# Parse data into interface
|
568
|
+
mode = self.option_manager.get_mode()
|
569
|
+
if mode == "Optimization":
|
570
|
+
if (os.path.exists(os.path.join(folder, 'error.txt'))):
|
571
|
+
data = hp.parse_pso_error(os.path.join(folder, 'error.txt'), len(self.option_manager.get_steps()))
|
572
|
+
print(data)
|
573
|
+
self.progress_data = data["data"]
|
574
|
+
self.footer_progress_bar.stop()
|
575
|
+
self.footer_progress_bar.configure(mode="determinate")
|
576
|
+
self.footer_progress_bar.set(data["percent"]/100)
|
577
|
+
self.footer_progress_label.configure(text="Round: " + str(data["round"]) + " - Step: " + str(data["step"]))
|
578
|
+
else:
|
579
|
+
if (os.path.exists(os.path.join(folder, 'output.txt'))):
|
580
|
+
data = hp.parse_sampling_output(os.path.join(folder, 'output.txt'))
|
581
|
+
print(data)
|
582
|
+
self.footer_progress_bar.stop()
|
583
|
+
self.footer_progress_bar.configure(mode="determinate")
|
584
|
+
self.footer_progress_bar.set(data["percent"]/100)
|
585
|
+
self.footer_progress_label.configure(text=str(round(data["percent"])) + "%")
|
602
586
|
|
603
587
|
|
604
588
|
|
@@ -611,13 +595,25 @@ class App(customtkinter.CTk):
|
|
611
595
|
self.footer_progress_bar.configure(mode="indeterminate")
|
612
596
|
#self.progress_bar.start()
|
613
597
|
self.footer_progress_bar.start()
|
614
|
-
self.progress_message_left.configure(text="")
|
615
|
-
self.progress_message_middle.configure(text="
|
616
|
-
self.progress_message_right.configure(text="")
|
617
|
-
self.textbox.insert("0.0", "\
|
618
|
-
|
619
|
-
|
620
|
-
|
598
|
+
#self.progress_message_left.configure(text="")
|
599
|
+
#self.progress_message_middle.configure(text="Job finished!")
|
600
|
+
#self.progress_message_right.configure(text="")
|
601
|
+
self.textbox.insert("0.0", "\nJob finished!\n")
|
602
|
+
|
603
|
+
# IF "./crash.txt" exists write it to the textbox
|
604
|
+
if (os.path.exists(os.path.join(folder, 'crash.txt'))):
|
605
|
+
with open(os.path.join(folder, 'crash.txt'), 'r') as f:
|
606
|
+
lines = f.readlines()
|
607
|
+
lines_string = "".join(lines)
|
608
|
+
print("CRASH OCCURRED!")
|
609
|
+
print(lines_string)
|
610
|
+
self.textbox.insert('0.0', lines_string)
|
611
|
+
self.textbox.insert('0.0', "CRASH OCCURRED!\n")
|
612
|
+
# Delete the file
|
613
|
+
os.remove(os.path.join(folder, 'crash.txt'))
|
614
|
+
|
615
|
+
def get_color(class_name, property = "fg_color"):
|
616
|
+
return ThemeManager.theme[class_name][property]
|
621
617
|
|
622
618
|
def start():
|
623
619
|
app = App()
|