mg-pso-gui 0.1.13__tar.gz → 0.1.87__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/PKG-INFO +1 -1
  2. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mg_pso_gui.egg-info/PKG-INFO +1 -1
  3. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mg_pso_gui.egg-info/SOURCES.txt +3 -0
  4. mg-pso-gui-0.1.87/mgpsogui/gui/HomePage.py +659 -0
  5. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/OptionManager.py +21 -1
  6. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/RunTab/RunTab.py +1 -20
  7. mg-pso-gui-0.1.87/mgpsogui/gui/SetupTab/OptimalParameterView.py +47 -0
  8. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/SetupTab/SetupTab.py +13 -2
  9. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/SetupTab/StepView.py +13 -6
  10. mg-pso-gui-0.1.87/mgpsogui/gui/VisualizeTab/SideBar.py +262 -0
  11. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/VisualizeTab/VisualizeTab.py +9 -5
  12. mg-pso-gui-0.1.87/mgpsogui/gui/images/test.png +0 -0
  13. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/util/GraphGenerator.py +197 -0
  14. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/util/PSORunner.py +8 -81
  15. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/util/recosu/pso/csip_access.py +2 -35
  16. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/util/recosu/pso/pso.py +5 -50
  17. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/setup.py +1 -1
  18. mg-pso-gui-0.1.13/mgpsogui/gui/HomePage.py +0 -572
  19. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mg_pso_gui.egg-info/dependency_links.txt +0 -0
  20. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mg_pso_gui.egg-info/entry_points.txt +0 -0
  21. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mg_pso_gui.egg-info/requires.txt +0 -0
  22. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mg_pso_gui.egg-info/top_level.txt +0 -0
  23. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/__init__.py +0 -0
  24. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/PlatformTab/PlatformTab.py +0 -0
  25. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/PlatformTab/__init__.py +0 -0
  26. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/RunTab/__init__.py +0 -0
  27. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/SetupTab/BoundsEditorWindow.py +0 -0
  28. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/SetupTab/BoundsList.py +0 -0
  29. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/SetupTab/CalibrationParametersView.py +0 -0
  30. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/SetupTab/FunctionsList.py +0 -0
  31. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/SetupTab/ListParametersView.py +0 -0
  32. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/SetupTab/StaticParameterView.py +0 -0
  33. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/SetupTab/__init__.py +0 -0
  34. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/VisualizeTab/__init__.py +0 -0
  35. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/__init__.py +0 -0
  36. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/images/IGOW 4 Logo.png +0 -0
  37. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/images/collapse.png +0 -0
  38. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/images/down.png +0 -0
  39. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/images/expand.png +0 -0
  40. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/images/play.png +0 -0
  41. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/images/refresh.png +0 -0
  42. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/images/refresh_hd.png +0 -0
  43. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/images/stop.png +0 -0
  44. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/images/trash.png +0 -0
  45. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/gui/images/up.png +0 -0
  46. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/mgpsogui.py +0 -0
  47. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/start.yaml +0 -0
  48. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/util/CTkToolTip/__init__.py +0 -0
  49. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/util/CTkToolTip/ctk_tooltip.py +0 -0
  50. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/util/__init__.py +0 -0
  51. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/util/recosu/__init__.py +0 -0
  52. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/util/recosu/pso/__init__.py +0 -0
  53. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/util/recosu/utils/__init__.py +0 -0
  54. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/util/recosu/utils/plot/__init__.py +0 -0
  55. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/util/recosu/utils/plot/cost_steps.py +0 -0
  56. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/util/recosu/utils/trace_writer.py +0 -0
  57. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/mgpsogui/util/recosu/utils/utils.py +0 -0
  58. {mg-pso-gui-0.1.13 → mg-pso-gui-0.1.87}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mg-pso-gui
3
- Version: 0.1.13
3
+ Version: 0.1.87
4
4
  Summary: GUI for MG-PSO
5
5
  Author: Robert Cordingly
6
6
  Author-email: <rcording@uw.ed>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mg-pso-gui
3
- Version: 0.1.13
3
+ Version: 0.1.87
4
4
  Summary: GUI for MG-PSO
5
5
  Author: Robert Cordingly
6
6
  Author-email: <rcording@uw.ed>
@@ -20,10 +20,12 @@ mgpsogui/gui/SetupTab/BoundsList.py
20
20
  mgpsogui/gui/SetupTab/CalibrationParametersView.py
21
21
  mgpsogui/gui/SetupTab/FunctionsList.py
22
22
  mgpsogui/gui/SetupTab/ListParametersView.py
23
+ mgpsogui/gui/SetupTab/OptimalParameterView.py
23
24
  mgpsogui/gui/SetupTab/SetupTab.py
24
25
  mgpsogui/gui/SetupTab/StaticParameterView.py
25
26
  mgpsogui/gui/SetupTab/StepView.py
26
27
  mgpsogui/gui/SetupTab/__init__.py
28
+ mgpsogui/gui/VisualizeTab/SideBar.py
27
29
  mgpsogui/gui/VisualizeTab/VisualizeTab.py
28
30
  mgpsogui/gui/VisualizeTab/__init__.py
29
31
  mgpsogui/gui/images/IGOW 4 Logo.png
@@ -34,6 +36,7 @@ mgpsogui/gui/images/play.png
34
36
  mgpsogui/gui/images/refresh.png
35
37
  mgpsogui/gui/images/refresh_hd.png
36
38
  mgpsogui/gui/images/stop.png
39
+ mgpsogui/gui/images/test.png
37
40
  mgpsogui/gui/images/trash.png
38
41
  mgpsogui/gui/images/up.png
39
42
  mgpsogui/util/GraphGenerator.py
@@ -0,0 +1,659 @@
1
+ #!/usr/local/bin/python3.9
2
+
3
+ import os
4
+ import time
5
+ dir_path = os.path.dirname(os.path.realpath(__file__))
6
+ os.chdir(dir_path)
7
+ print(dir_path)
8
+
9
+ # minikube kubectl -- create -f ../start.yaml ; sleep 60 ; minikube service pf8087-csu-csip-oms -n csip
10
+
11
+ import requests
12
+
13
+ import tkinter as tk
14
+ import tkinter.messagebox
15
+ import customtkinter
16
+ import json
17
+ import os
18
+ from PIL import Image, ImageTk
19
+ import traceback
20
+ from multiprocessing import Process
21
+ from multiprocessing import Queue
22
+ import re
23
+ import pandas as pd
24
+ import numpy as np
25
+ import ast
26
+ import platform
27
+ import time
28
+
29
+ from queue import Empty
30
+
31
+ from ..util import PSORunner
32
+ from ..util import GraphGenerator
33
+ from ..util.CTkToolTip import CTkToolTip as ctt
34
+
35
+ import subprocess
36
+ import plotly.express as px
37
+ import plotly.graph_objs as go
38
+
39
+ from tkinter.filedialog import askopenfilename
40
+ from tkinter.filedialog import asksaveasfilename
41
+
42
+ from . import OptionManager as om
43
+
44
+ from .SetupTab import SetupTab as st
45
+ from .PlatformTab import PlatformTab as pt
46
+ from .RunTab import RunTab as rt
47
+ from .VisualizeTab import VisualizeTab as vt
48
+
49
+ from ..util.CTkToolTip import CTkToolTip as ctt
50
+
51
+ customtkinter.set_appearance_mode("Dark") # Modes: "System" (standard), "Dark", "Light"
52
+ customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue"
53
+
54
+ results_queue = Queue()
55
+ stdout_queue = Queue()
56
+ stderr_queue = Queue()
57
+ cosu_queue = Queue()
58
+
59
+ class App(customtkinter.CTk):
60
+ def __init__(self):
61
+ super().__init__()
62
+
63
+ self.option_manager = om.OptionManager()
64
+
65
+ self.graph_selector_value = tk.StringVar()
66
+ self.graph_selector_value.set("Best Cost Stacked")
67
+
68
+ self.selected_csv = tk.StringVar()
69
+ self.selected_csv.set("No files found...")
70
+ self.open_file = "None"
71
+ self.csv_data = None
72
+
73
+ self.selected_csv2 = tk.StringVar()
74
+ self.selected_csv2.set("No files found...")
75
+ self.open_file2 = "None"
76
+ self.csv_data2 = None
77
+
78
+ self.selected_x = tk.StringVar()
79
+ self.selected_x.set("time")
80
+
81
+ self.selected_y1 = tk.StringVar()
82
+ self.selected_y1.set("NONE")
83
+
84
+ self.selected_y2 = tk.StringVar()
85
+ self.selected_y2.set("NONE")
86
+
87
+ self.running_config = None
88
+ self.selected_graph_name = None
89
+
90
+ self.train_process = None
91
+ self.minikube_process = None
92
+ self.data_x = [0]
93
+ self.data_y = [0]
94
+
95
+ self.image_scale = 1
96
+ self.image_width = 1280
97
+ self.image_height = 720
98
+ self.progress_data = None
99
+ self.calibration_data = None
100
+ self.testing = False
101
+
102
+ # configure window
103
+ self.title("CSIP PSO")
104
+ self.geometry(f"{1920}x{1080}")
105
+
106
+ # configure grid layout (4x4)
107
+ self.grid_columnconfigure(0, weight=1)
108
+ self.grid_rowconfigure(1, weight=1)
109
+
110
+ header_padding_x = (5, 5)
111
+ header_padding_y = (10, 10)
112
+
113
+ self.sidebar_frame = customtkinter.CTkFrame(self, width=140, corner_radius=0)
114
+ self.sidebar_frame.grid(row=0, column=0, sticky="nsew")
115
+ self.sidebar_frame.grid_columnconfigure(4, weight=1)
116
+ self.logo_label = customtkinter.CTkLabel(self.sidebar_frame, text="CSIP PSO", font=customtkinter.CTkFont(size=20, weight="bold"))
117
+ self.logo_label.grid(row=0, column=0, padx=(20, 10), pady=header_padding_y)
118
+ self.save_button = customtkinter.CTkButton(self.sidebar_frame, text="Save", width=60, command=self.save_project)
119
+ self.save_button.grid(row=0, column=1, padx=header_padding_x, pady=header_padding_y)
120
+ self.load_button = customtkinter.CTkButton(self.sidebar_frame, text="Load", width=60, command=self.load_project)
121
+ self.load_button.grid(row=0, column=2, padx=header_padding_x, pady=header_padding_y)
122
+
123
+ # 4 is service URL
124
+ self.service_label = customtkinter.CTkLabel(self.sidebar_frame, text="Service:", anchor="w")
125
+ self.service_label.grid(row=0, column=3, padx=(80, 5), pady=header_padding_y)
126
+ self.service_url = customtkinter.CTkEntry(self.sidebar_frame, textvariable=self.option_manager.get_arguments()['url'])
127
+ self.service_url.grid(row=0, column=4, columnspan=1, padx=header_padding_x, pady=header_padding_y, sticky="nsew")
128
+ refresh_image = customtkinter.CTkImage(Image.open(os.path.join("./images", "refresh.png")), size=(20, 20))
129
+ self.refresh_button = customtkinter.CTkButton(self.sidebar_frame, text=None, width=30, image=refresh_image, command=self.load)
130
+ ctt(self.refresh_button, delay=0.1, alpha=0.95, message="Connect to Service")
131
+ self.refresh_button.grid(row=0, column=5, padx=(5, 80), pady=header_padding_y)
132
+
133
+ self.scaling_label = customtkinter.CTkLabel(self.sidebar_frame, text="Scale:", anchor="w")
134
+ self.scaling_label.grid(row=0, column=6, padx=header_padding_x, pady=header_padding_y)
135
+ self.scaling_optionemenu = customtkinter.CTkOptionMenu(self.sidebar_frame, values=["50%", "75%", "100%", "125%", "150%", "175%", "200%"], width=60,
136
+ command=self.change_scaling_event)
137
+ self.scaling_optionemenu.grid(row=0, column=7, padx=header_padding_x, pady=header_padding_y)
138
+ self.scaling_optionemenu.set("100%")
139
+
140
+ expand_image = customtkinter.CTkImage(Image.open(os.path.join("./images", "expand.png")), size=(20, 20))
141
+ self.new_window = customtkinter.CTkButton(self.sidebar_frame, text=None, width=30, image=expand_image, command=self.new_window)
142
+ ctt(self.new_window, delay=0.1, alpha=0.95, message="Open New Window")
143
+ self.new_window.grid(row=0, column=8, padx=(5, 20), pady=header_padding_y)
144
+
145
+ self.tabview = customtkinter.CTkTabview(self, bg_color="transparent", fg_color="transparent")
146
+ self.tabview.grid(row=1, column=0, padx=(0, 0), pady=(10, 10), sticky="nsew")
147
+ tab1 = "Platform"
148
+ tab2 = "Setup"
149
+ tab3 = "Logs"
150
+ tab4 = "Results"
151
+ #tab5 = "Results"
152
+
153
+ self.tabview.add(tab1)
154
+ self.tabview.add(tab2)
155
+ self.tabview.add(tab4)
156
+ self.tabview.add(tab3)
157
+ #self.tabview.add(tab5)
158
+
159
+ #self.tabview.configure(state="disabled")
160
+
161
+ pt.create_tab(self, self.tabview.tab(tab1))
162
+ st.create_tab(self, self.tabview.tab(tab2))
163
+ rt.create_tab(self, self.tabview.tab(tab3))
164
+ vt.create_tab(self, self.tabview.tab(tab4))
165
+
166
+ self.footer_frame = customtkinter.CTkFrame(self, corner_radius=0)
167
+ self.footer_frame.grid(row=2, column=0, sticky="nsew")
168
+ self.footer_frame.grid_columnconfigure(4, weight=1)
169
+
170
+ self.footer_progress_label = customtkinter.CTkLabel(self.footer_frame, text="Stopped", width=150, font=customtkinter.CTkFont(size=16, weight="bold"), anchor="w")
171
+ self.footer_progress_label.grid(row=0, column=0, padx=(20, 5), pady=header_padding_y)
172
+
173
+ self.footer_progress_bar = customtkinter.CTkProgressBar(self.footer_frame)
174
+ self.footer_progress_bar.grid(row=0, column=4, padx=(50, 100), pady=header_padding_y, sticky="ew")
175
+ self.footer_progress_bar.set(0)
176
+
177
+ self.algorithm_optionmenu = customtkinter.CTkOptionMenu(self.footer_frame, variable=self.option_manager.get_arguments()['mode'], values=["PSO", "Halton"], width=50)
178
+ self.algorithm_optionmenu.grid(row=0, column=6, padx=header_padding_x, pady=header_padding_y)
179
+ self.algorithm_optionmenu.set("PSO")
180
+
181
+ play_image = customtkinter.CTkImage(Image.open(os.path.join("./images", "play.png")), size=(20, 20))
182
+ self.run_button = customtkinter.CTkButton(self.footer_frame, text=None, width=30, image=play_image, command=self.run)
183
+ ctt(self.run_button, delay=0.1, alpha=0.95, message="Start Calibration")
184
+ self.run_button.grid(row=0, column=7, padx=(20, 5), pady=header_padding_y)
185
+
186
+ test_image = customtkinter.CTkImage(Image.open(os.path.join("./images", "test.png")), size=(20, 20))
187
+ self.test_button = customtkinter.CTkButton(self.footer_frame, text=None, width=30, image=test_image, command=self.run_test)
188
+ ctt(self.test_button, delay=0.1, alpha=0.95, message="Start Testing")
189
+ self.test_button.grid(row=0, column=8, padx=(5, 5), pady=header_padding_y)
190
+
191
+ stop_image = customtkinter.CTkImage(Image.open(os.path.join("./images", "stop.png")), size=(20, 20))
192
+ self.stop_button = customtkinter.CTkButton(self.footer_frame, text=None, width=30, image=stop_image, command=self.stop)
193
+ ctt(self.stop_button, delay=0.1, alpha=0.95, message="Stop")
194
+ self.stop_button.grid(row=0, column=9, padx=(5, 20), pady=header_padding_y)
195
+
196
+ download_image = customtkinter.CTkImage(Image.open(os.path.join("./images", "down.png")), size=(20, 20))
197
+ self.download_button = customtkinter.CTkButton(self.footer_frame, text=None, width=30, image=download_image, command=self.stop)
198
+ ctt(self.download_button, delay=0.1, alpha=0.95, message="Download Results")
199
+ self.download_button.grid(row=0, column=10, padx=(5, 20), pady=header_padding_y)
200
+
201
+ self.after(1000, self.running_loop)
202
+
203
+ def update_graph(self, value):
204
+ self.vis_sidebar.refresh()
205
+ GraphGenerator.generate_graphs(self)
206
+
207
+ '''def _resize_image(self, event):
208
+ self.graph_label.update_idletasks()
209
+ new_width = self.graph_label.winfo_width()
210
+ new_height = self.graph_label.winfo_height()
211
+
212
+ alt_width = new_height * 1.77778
213
+ alt_height = new_width / 1.77778
214
+
215
+ if (new_width < new_height):
216
+ new_height = alt_height
217
+ else:
218
+ new_width = alt_width
219
+
220
+ self.image_width = new_width
221
+ self.image_height = new_height
222
+
223
+ self.graph_image = customtkinter.CTkImage(self.graph_image_obj, size=(new_width, new_height))
224
+ self.graph_label.configure(image=self.graph_image)
225
+ self.graph_label.update_idletasks()
226
+
227
+
228
+ def update_graph(self, value):
229
+ selected_graph = self.graph_selector_value.get()
230
+ info = self.option_manager.get_project_data()
231
+ folder = os.path.join(info['path'], info['name'])
232
+
233
+ if not os.path.exists(folder):
234
+ os.makedirs(folder)
235
+
236
+ if (selected_graph == "Best Cost Stacked"):
237
+ self.selected_graph_name = "best_cost_stacked"
238
+ elif (selected_graph == "Best Cost by Round"):
239
+ self.selected_graph_name = "best_cost_by_round"
240
+ elif (selected_graph == "Iteration Table"):
241
+ self.selected_graph_name = "table"
242
+ elif (selected_graph == "Calibrated Parameters"):
243
+ self.selected_graph_name = "calibrated_params_by_round"
244
+
245
+ image_path = os.path.join(folder, self.selected_graph_name + ".png")
246
+ if not os.path.exists(image_path):
247
+ image_path = os.path.join("./images", "up.png")
248
+ self.graph_image_obj = Image.open(image_path)
249
+ self.graph_image = customtkinter.CTkImage(self.graph_image_obj, size=(self.image_width * self.image_scale, self.image_height * self.image_scale))
250
+ self.graph_label.configure(image=self.graph_image)'''
251
+
252
+ def save_project(self):
253
+ metrics = self.option_manager.get_metrics()
254
+
255
+ # Add the calibration_progress dataframe to the json
256
+ if (self.progress_data is not None):
257
+ metrics["calibration_progress"] = self.progress_data.to_json()
258
+ # Add the calibration_data to the json
259
+ if (self.calibration_data is not None):
260
+ metrics["calibration_data"] = self.calibration_data
261
+
262
+ filename = asksaveasfilename(filetypes=[("JSON", "*.json")], initialfile="config", defaultextension="json", title="Save Project")
263
+
264
+ try:
265
+
266
+ # Convert metrics to json and save to file with proper spacing
267
+ with open(filename, "w") as f:
268
+ f.write(json.dumps(metrics, indent=4))
269
+
270
+ self.save_button.configure(text="Saved!")
271
+ self.after(3000, lambda: self.save_button.configure(text="Save"))
272
+ except Exception as e:
273
+ self.save_button.configure(text="Error!")
274
+ print(e)
275
+ self.after(3000, lambda: self.save_button.configure(text="Save"))
276
+
277
+ def new_window(self):
278
+ # Shell out and run ./main.py
279
+ subprocess.Popen(["python3", "../mgpsogui.py"])
280
+
281
+ def load_project(self):
282
+
283
+ filename = askopenfilename(filetypes=[("JSON", "*.json")], title="Open Project", multiple=False)
284
+ print(filename)
285
+
286
+ try:
287
+
288
+ # Load config.json and convert to metrics
289
+ with open(filename, "r") as f:
290
+ metrics = json.loads(f.read())
291
+
292
+ self.option_manager.set_path(filename)
293
+
294
+ if "arguments" in metrics:
295
+ metrics["arguments"]["calibration_parameters"] = metrics["calibration_parameters"]
296
+
297
+ if "service_parameters" in metrics:
298
+ self.option_manager.set_service_parameters(metrics["service_parameters"])
299
+ self.tabview.configure(state="enabled")
300
+
301
+ if "calibration_progress" in metrics:
302
+ self.progress_data = pd.read_json(metrics["calibration_progress"])
303
+ self.calibration_data = metrics["calibration_data"]
304
+ print(self.progress_data)
305
+
306
+ if "calibration_data" in metrics:
307
+ self.calibration_data = metrics["calibration_data"]
308
+ print(self.calibration_data)
309
+
310
+ print(metrics)
311
+
312
+ self.option_manager.clear()
313
+ self.option_manager.add_arguments(metrics["arguments"])
314
+ self.option_manager.add_steps(metrics["steps"])
315
+
316
+ self.steps_frame.clear()
317
+ self.steps_frame.render()
318
+
319
+ self.static_param_frame.clear()
320
+ self.static_param_frame.render()
321
+
322
+ self.calib_param_frame.clear()
323
+ self.calib_param_frame.render()
324
+
325
+ self.optimal_param_frame.clear()
326
+ self.optimal_param_frame.render()
327
+
328
+ info = self.option_manager.get_project_data()
329
+ folder = os.path.join(info['path'], info['name'])
330
+ self.HRU_data = pd.read_csv(os.path.join(folder, "results", "HRU_1.csv"), skiprows=3)
331
+ print(self.HRU_data)
332
+
333
+ self.load_button.configure(text="Loaded!")
334
+ self.after(3000, lambda: self.load_button.configure(text="Load"))
335
+
336
+ except Exception as e:
337
+ print(e)
338
+ self.load_button.configure(text="Error!")
339
+ self.after(3000, lambda: self.load_button.configure(text="Load"))
340
+
341
+ def change_appearance_mode_event(self, new_appearance_mode: str):
342
+ customtkinter.set_appearance_mode(new_appearance_mode)
343
+
344
+ def change_scaling_event(self, new_scaling: str):
345
+ new_scaling_float = int(new_scaling.replace("%", "")) / 100
346
+ customtkinter.set_widget_scaling(new_scaling_float)
347
+
348
+ def change_scaling_event(self, new_scaling: str):
349
+ new_scaling_float = int(new_scaling.replace("%", "")) / 100
350
+ customtkinter.set_widget_scaling(new_scaling_float)
351
+
352
+ def make_request(self):
353
+ service_url = self.service_url.get()
354
+ try:
355
+ response = requests.get(service_url)
356
+
357
+ response_json = json.loads(response.text)
358
+ status = response.status_code
359
+
360
+ self.option_manager.set_service_parameters(response_json)
361
+
362
+ self.service_status.delete('0.0', tk.END)
363
+ self.service_status.insert(text=str(status), index='0.0')
364
+ self.service_name.delete('0.0', tk.END)
365
+ self.service_name.insert(text=str(response_json["metainfo"]["name"]), index='0.0')
366
+ self.service_description.delete('0.0', tk.END)
367
+ self.service_description.insert(text=str(response_json["metainfo"]["description"]), index='0.0')
368
+ self.service_details.delete('0.0', tk.END)
369
+ self.service_details.insert(text=json.dumps(response_json, indent=4), index='0.0')
370
+
371
+ self.refresh_button.configure(fg_color="green")
372
+ except Exception as e:
373
+ self.refresh_button.configure(fg_color="red")
374
+
375
+
376
+ def load(self):
377
+ # Make HTTP request to service_url and save the result to bounds.json
378
+
379
+ self.default_button_color = self.refresh_button.cget("fg_color")
380
+
381
+ self.refresh_button.configure(fg_color="gray")
382
+
383
+ self.after(10, self.make_request)
384
+ self.after(3000, lambda: self.refresh_button.configure(fg_color=self.default_button_color))
385
+
386
+ def run_test(self):
387
+ self.testing = True
388
+ self.run()
389
+
390
+ def run(self):
391
+ metrics = self.option_manager.get_metrics()
392
+ self.running_config = metrics
393
+
394
+ if self.testing:
395
+ steps = metrics['steps']
396
+ for step in steps:
397
+ for param in step['param']:
398
+ param['default_value'] = param['optimal_value']
399
+ self.testing = False
400
+
401
+ self.progress_data = None
402
+ self.calibration_data = None
403
+
404
+ #self.progress_bar.configure(mode="indeterminnate")
405
+ #self.progress_bar.start()
406
+ self.footer_progress_bar.configure(mode="indeterminnate")
407
+ self.footer_progress_bar.start()
408
+
409
+ self.data_x = [0]
410
+ self.data_y = [0]
411
+
412
+ self.progress_message_middle.configure(text="Calibration starting...")
413
+ self.footer_progress_label.configure(text="Starting...")
414
+
415
+ self.textbox.insert("0.0", "Starting calibration...\n\n")
416
+ self.textbox.insert("0.0", "Calibration Parameters:\n")
417
+ self.textbox.insert("0.0", json.dumps(metrics, indent=4) + "\n\n")
418
+ try:
419
+ info = self.option_manager.get_project_data()
420
+ folder = os.path.join(info['path'], info['name'])
421
+
422
+ if not os.path.exists(folder):
423
+ os.makedirs(folder)
424
+
425
+ if (os.path.exists(os.path.join(folder, 'output.txt'))):
426
+ os.remove(os.path.join(folder, 'output.txt'))
427
+
428
+ if (os.path.exists(os.path.join(folder, 'error.txt'))):
429
+ os.remove(os.path.join(folder, 'error.txt'))
430
+
431
+ self.train_process = Process(target=PSORunner.run_process, args=(stdout_queue, stderr_queue, results_queue, cosu_queue, metrics, folder))
432
+ self.train_process.daemon = True
433
+ self.train_process.start()
434
+ self.after(1000, self.watch_loop)
435
+ self.string_cache = ""
436
+ self.data_cache = ""
437
+
438
+ except Exception as e:
439
+ self.textbox.insert("0.0", "An exception occurred!\n Exception: " + str(e) + "\n\n")
440
+ self.textbox.insert("0.0", "Stack trace:\n")
441
+ self.textbox.insert("0.0", traceback.format_exc())
442
+ self.textbox.insert("0.0", "\n\n")
443
+ self.textbox.insert("0.0", "Calibration failed!")
444
+ self.progress_message_left.configure(text="")
445
+ self.progress_message_middle.configure(text="Calibration failed! See error log below.")
446
+ self.progress_message_right.configure(text="")
447
+ self.footer_progress_label.configure(text="Failed")
448
+ #self.progress_bar.stop()
449
+ self.footer_progress_bar.stop()
450
+ #self.progress_bar.configure(mode="determinate")
451
+ self.footer_progress_bar.configure(mode="determinate")
452
+ #self.progress_bar.set(0)
453
+ self.footer_progress_bar.set(0)
454
+
455
+ def stop(self):
456
+ print("Stopping...")
457
+ self.train_process.terminate()
458
+
459
+ info = self.option_manager.get_project_data()
460
+ folder = os.path.join(info['path'], info['name'])
461
+
462
+ if not os.path.exists(folder):
463
+ os.makedirs(folder)
464
+
465
+ # Stop the process
466
+ if (os.path.exists(os.path.join(folder, 'output.txt'))):
467
+ os.remove(os.path.join(folder, 'output.txt'))
468
+
469
+ if (os.path.exists(os.path.join(folder, 'error.txt'))):
470
+ os.remove(os.path.join(folder, 'error.txt'))
471
+
472
+ self.textbox.insert("0.0", "\nCalibration terminated!\n")
473
+ #self.progress_bar.stop()
474
+ self.footer_progress_bar.stop()
475
+ #self.progress_bar.configure(mode="determinate")
476
+ self.footer_progress_bar.configure(mode="determinate")
477
+ #self.progress_bar.set(0)
478
+ self.footer_progress_bar.set(0)
479
+ self.progress_message_left.configure(text="")
480
+ self.progress_message_middle.configure(text="Calibration stopped!")
481
+ self.footer_progress_label.configure(text="Stopped")
482
+ self.progress_message_right.configure(text="")
483
+
484
+ def running_loop(self):
485
+ try:
486
+ active_tab = self.tabview.get()
487
+ if (active_tab == "Results"):
488
+ GraphGenerator.generate_graphs(self)
489
+ finally:
490
+ self.after(1000, self.running_loop)
491
+
492
+ def watch_loop(self):
493
+ # Check if file exists:
494
+ info = self.option_manager.get_project_data()
495
+ folder = os.path.join(info['path'], info['name'])
496
+
497
+ if not os.path.exists(folder):
498
+ os.makedirs(folder)
499
+
500
+ while True:
501
+ try:
502
+ stdout_line = stdout_queue.get_nowait()
503
+
504
+ print("# " + stdout_line, flush=True)
505
+ with open(os.path.join(folder, 'output.txt'), 'a') as f:
506
+ f.write(stdout_line)
507
+
508
+ except Empty:
509
+ break
510
+
511
+ while True:
512
+ try:
513
+ stderr_line = stderr_queue.get_nowait()
514
+
515
+ print("? " + stderr_line, flush=True)
516
+ with open(os.path.join(folder, 'error.txt'), 'a') as f:
517
+ f.write(stderr_line)
518
+
519
+ except Empty:
520
+ break
521
+
522
+ while True:
523
+ try:
524
+ cosu_line = cosu_queue.get_nowait()
525
+
526
+ print("COSU " + cosu_line, flush=True)
527
+ except Empty:
528
+ break
529
+
530
+ while True:
531
+ try:
532
+ trace = results_queue.get_nowait()
533
+
534
+ print("TRACE " + str(trace), flush=True)
535
+ except Empty:
536
+ break
537
+ except Exception as e:
538
+ print("Some error happened when getting the trace!")
539
+ print(e)
540
+
541
+ if (os.path.exists(os.path.join(folder, 'output.txt'))):
542
+ with open(os.path.join(folder, 'output.txt'), 'r') as f:
543
+ lines = f.readlines()
544
+ lines_string = "".join(lines)
545
+
546
+ new_characters = lines_string.replace(self.string_cache, "")
547
+ # Update the textbox with characters not in self.string_cache
548
+ self.textbox.insert('0.0', new_characters)
549
+ self.string_cache = lines_string
550
+ print(new_characters, end="")
551
+
552
+ try:
553
+ with open(os.path.join(folder, "output.txt"), "r") as f:
554
+ text = f.read()
555
+
556
+ calibrated_params_pattern = r"calibrated params: ({.*?})"
557
+ best_particle_values_pattern = r"best particle values: (\[.*?\])"
558
+ progress_pattern = r"Progress - best_round_cost:(.*?), rel_round_tol:(.*?), rtol:(.*?)\n"
559
+
560
+ calibrated_params = re.findall(calibrated_params_pattern, text)
561
+ best_particle_values = re.findall(best_particle_values_pattern, text)
562
+ progress_values = re.findall(progress_pattern, text)
563
+
564
+ for index, pp in enumerate(best_particle_values):
565
+ pp = pp.strip()
566
+ pp = pp.replace('[ ', '[')
567
+ pp = pp.replace(' ', ',')
568
+ pp = pp.replace(' ', ',')
569
+ best_particle_values[index] = pp
570
+
571
+ calibrated_params = [ast.literal_eval(i) for i in calibrated_params]
572
+ best_particle_values = [ast.literal_eval(i) for i in best_particle_values]
573
+ progress_values = [tuple(map(float, i)) for i in progress_values]
574
+
575
+ #print("Current params: " + str(calibrated_params), flush=True)
576
+
577
+ self.calibration_data = calibrated_params
578
+
579
+ #GraphGenerator.calibrated_params_by_round(self.running_config['steps'], calibrated_params, self.option_manager)
580
+ #self.update_graph("")
581
+ except Exception as e:
582
+ # Print stack trace
583
+ traceback.print_exc()
584
+
585
+ print(e)
586
+
587
+ if (os.path.exists(os.path.join(folder, 'error.txt'))):
588
+ with open(os.path.join(folder, 'error.txt'), 'r') as f:
589
+ lines = f.readlines()
590
+ lines_string = "".join(lines)
591
+ self.data_cache = lines_string
592
+
593
+ pattern = r'(\d+)%\|.*\|(\d+)/(\d+)(?:,\sbest_cost=(\d+\.\d+))?' # The magic of AI
594
+ matches = re.findall(pattern, self.data_cache)
595
+ filtered_matches = [match for match in matches if match[3] != '']
596
+ matches = filtered_matches
597
+
598
+ if len(matches) > 0:
599
+ df = pd.DataFrame(matches, columns=['percent', 'completed_rounds', 'total_rounds', 'best_cost'], dtype=float)
600
+ df = df[df['best_cost'] != '']
601
+ df = df.dropna()
602
+ df = df.drop_duplicates()
603
+ df['round_step'] = (df['completed_rounds'].diff() < 0).cumsum()
604
+ df = df.drop_duplicates(subset=['completed_rounds', 'round_step'])
605
+ self.progress_data = df
606
+
607
+ match = matches[-1]
608
+ percent = int(match[0])
609
+ completed_rounds = int(match[1])
610
+ total_rounds = int(match[2])
611
+ best_cost = float(match[3]) if match[3] else None
612
+
613
+ if (percent > 0):
614
+ #self.progress_bar.stop()
615
+ self.footer_progress_bar.stop()
616
+ #self.progress_bar.configure(mode="determinate")
617
+ self.footer_progress_bar.configure(mode="determinate")
618
+ #self.progress_bar.set(percent/100)
619
+ self.footer_progress_bar.set(percent/100)
620
+ self.progress_message_left.configure(text="Percent Complete: " + str(percent) + "%")
621
+ self.progress_message_middle.configure(text=str(completed_rounds) + "/" + str(total_rounds))
622
+ self.footer_progress_label.configure(text=str(completed_rounds) + "/" + str(total_rounds))
623
+ self.progress_message_right.configure(text="Best Cost: " + str(best_cost))
624
+ else:
625
+ #self.progress_bar.configure(mode="indeterminate")
626
+ self.footer_progress_bar.configure(mode="indeterminate")
627
+ #self.progress_bar.start()
628
+ self.footer_progress_bar.start()
629
+ self.progress_message_left.configure(text="")
630
+ self.progress_message_middle.configure(text="Starting new round...")
631
+ self.footer_progress_label.configure(text="Next round...")
632
+ self.progress_message_right.configure(text="")
633
+
634
+
635
+
636
+ if self.train_process.is_alive():
637
+ self.after(1000, self.watch_loop)
638
+ else:
639
+ #self.progress_bar.stop()
640
+ self.footer_progress_bar.stop()
641
+ #self.progress_bar.configure(mode="indeterminate")
642
+ self.footer_progress_bar.configure(mode="indeterminate")
643
+ #self.progress_bar.start()
644
+ self.footer_progress_bar.start()
645
+ self.progress_message_left.configure(text="")
646
+ self.progress_message_middle.configure(text="Calibration finished!")
647
+ self.progress_message_right.configure(text="")
648
+ self.textbox.insert("0.0", "\nCalibration finished!\n")
649
+
650
+
651
+
652
+
653
+ def start():
654
+ app = App()
655
+ app.mainloop()
656
+
657
+ if __name__ == "__main__":
658
+ app = App()
659
+ app.mainloop()