mg-pso-gui 0.1.40__py3-none-any.whl → 0.2.76__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. {mg_pso_gui-0.1.40.dist-info → mg_pso_gui-0.2.76.dist-info}/METADATA +10 -11
  2. mg_pso_gui-0.2.76.dist-info/RECORD +76 -0
  3. {mg_pso_gui-0.1.40.dist-info → mg_pso_gui-0.2.76.dist-info}/WHEEL +1 -1
  4. mgpsogui/gui/General/ParameterView.py +110 -0
  5. mgpsogui/gui/General/__init__.py +0 -0
  6. mgpsogui/gui/HomePage.py +234 -238
  7. mgpsogui/gui/OptionManager.py +333 -145
  8. mgpsogui/gui/OptionManager_backup.py +443 -0
  9. mgpsogui/gui/PlatformTab/PlatformTab.py +15 -6
  10. mgpsogui/gui/RunTab/OptimalParameterView.py +47 -0
  11. mgpsogui/gui/RunTab/RunTab.py +90 -17
  12. mgpsogui/gui/SetupTab/BoundsEditorWindow.py +1 -1
  13. mgpsogui/gui/SetupTab/BoundsList.py +97 -34
  14. mgpsogui/gui/SetupTab/CustomFunctionEditorWindow.py +74 -0
  15. mgpsogui/gui/SetupTab/CustomFunctionMetrics.py +156 -0
  16. mgpsogui/gui/SetupTab/FunctionsList.py +60 -6
  17. mgpsogui/gui/SetupTab/{StaticParameterView.py → ListEditor.py} +27 -16
  18. mgpsogui/gui/SetupTab/ListParametersView.py +7 -6
  19. mgpsogui/gui/SetupTab/{CalibrationParametersView.py → OverrideParameterMetrics.py} +35 -9
  20. mgpsogui/gui/SetupTab/OverrideParameterWindow.py +40 -0
  21. mgpsogui/gui/SetupTab/SetupTab.py +31 -11
  22. mgpsogui/gui/SetupTab/StepView.py +93 -22
  23. mgpsogui/gui/VisualizeTab/MatrixEditor.py +68 -0
  24. mgpsogui/gui/VisualizeTab/SideBar.py +358 -61
  25. mgpsogui/gui/VisualizeTab/VisualizeTab.py +69 -8
  26. mgpsogui/gui/defaults/__init__.py +0 -0
  27. mgpsogui/gui/defaults/optimization.json +176 -0
  28. mgpsogui/gui/defaults/sampling.json +111 -0
  29. mgpsogui/gui/defaults/sensitivity.json +20 -0
  30. mgpsogui/gui/images/plus.png +0 -0
  31. mgpsogui/util/GraphGenerator.py +721 -50
  32. mgpsogui/util/PSORunner.py +615 -86
  33. mgpsogui/util/debug.py +559 -0
  34. mgpsogui/util/helpers.py +95 -0
  35. mgpsogui/util/recosu/__init__.py +2 -1
  36. mgpsogui/util/recosu/pso/pso.py +55 -11
  37. mgpsogui/util/recosu/sampling/__init__.py +16 -0
  38. mgpsogui/util/recosu/sampling/halton/__init__.py +0 -0
  39. mgpsogui/util/recosu/sampling/halton/halton.py +45 -0
  40. mgpsogui/util/recosu/sampling/halton/prime.py +82 -0
  41. mgpsogui/util/recosu/sampling/random/__init__.py +0 -0
  42. mgpsogui/util/recosu/sampling/random/random_sampler.py +34 -0
  43. mgpsogui/util/recosu/sampling/sample_trace_writer.py +47 -0
  44. mgpsogui/util/recosu/sampling/sampler_task.py +75 -0
  45. mgpsogui/util/recosu/sampling/sampling.py +99 -0
  46. mgpsogui/util/sampler_test_driver.py +129 -0
  47. mg_pso_gui-0.1.40.dist-info/RECORD +0 -52
  48. mgpsogui/gui/images/IGOW 4 Logo.png +0 -0
  49. {mg_pso_gui-0.1.40.dist-info → mg_pso_gui-0.2.76.dist-info}/entry_points.txt +0 -0
  50. {mg_pso_gui-0.1.40.dist-info → mg_pso_gui-0.2.76.dist-info}/top_level.txt +0 -0
mgpsogui/gui/HomePage.py CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/local/bin/python3.9
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("Dark") # Modes: "System" (standard), "Dark", "Light"
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.selected_x = tk.StringVar()
74
- self.selected_x.set("time")
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("CSIP PSO")
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="CSIP PSO", font=customtkinter.CTkFont(size=20, weight="bold"))
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.get_arguments()['url'])
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=(5, 80), pady=header_padding_y)
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=6, padx=header_padding_x, pady=header_padding_y)
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
- command=self.change_scaling_event)
131
- self.scaling_optionemenu.grid(row=0, column=7, padx=header_padding_x, pady=header_padding_y)
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.new_window)
136
- ctt(self.new_window, delay=0.1, alpha=0.95, message="Open New Window")
137
- self.new_window.grid(row=0, column=8, padx=(5, 20), pady=header_padding_y)
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 = "Logs"
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 Calibration")
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.run)
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
- # Convert metrics to json and save to file with proper spacing
261
- with open(filename, "w") as f:
262
- f.write(json.dumps(metrics, indent=4))
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 new_window(self):
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
- # Load config.json and convert to metrics
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.static_param_frame.clear()
314
- self.static_param_frame.render()
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.calib_param_frame.clear()
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.set_service_parameters(response_json)
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=self.default_button_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="Calibration starting...")
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 calibration...\n\n")
396
- self.textbox.insert("0.0", "Calibration Parameters:\n")
397
- self.textbox.insert("0.0", json.dumps(metrics, indent=4) + "\n\n")
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
- info = self.option_manager.get_project_data()
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, cosu_queue, metrics, folder))
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", "Calibration failed!")
424
- self.progress_message_left.configure(text="")
425
- self.progress_message_middle.configure(text="Calibration failed! See error log below.")
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
- info = self.option_manager.get_project_data()
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
- os.remove(os.path.join(folder, 'output.txt'))
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
- os.remove(os.path.join(folder, 'error.txt'))
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", "\nCalibration terminated!\n")
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="Calibration stopped!")
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
- # Check if file exists:
474
- info = self.option_manager.get_project_data()
475
- folder = os.path.join(info['path'], info['name'])
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
- cosu_line = cosu_queue.get_nowait()
501
+ trace = results_queue.get_nowait()
505
502
 
506
- print("COSU " + cosu_line, flush=True)
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
- if (os.path.exists(os.path.join(folder, 'error.txt'))):
557
- with open(os.path.join(folder, 'error.txt'), 'r') as f:
558
- lines = f.readlines()
559
- lines_string = "".join(lines)
560
- self.data_cache = lines_string
561
-
562
- pattern = r'(\d+)%\|.*\|(\d+)/(\d+)(?:,\sbest_cost=(\d+\.\d+))?' # The magic of AI
563
- matches = re.findall(pattern, self.data_cache)
564
- filtered_matches = [match for match in matches if match[3] != '']
565
- matches = filtered_matches
566
-
567
- if len(matches) > 0:
568
- df = pd.DataFrame(matches, columns=['percent', 'completed_rounds', 'total_rounds', 'best_cost'], dtype=float)
569
- df = df[df['best_cost'] != '']
570
- df = df.dropna()
571
- df = df.drop_duplicates()
572
- df['round_step'] = (df['completed_rounds'].diff() < 0).cumsum()
573
- df = df.drop_duplicates(subset=['completed_rounds', 'round_step'])
574
- self.progress_data = df
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="Calibration finished!")
616
- self.progress_message_right.configure(text="")
617
- self.textbox.insert("0.0", "\nCalibration finished!\n")
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()