mg-pso-gui 0.2.99__py3-none-any.whl → 0.2.101__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mg-pso-gui
3
- Version: 0.2.99
3
+ Version: 0.2.101
4
4
  Summary: GUI for MG-PSO
5
5
  Author: Robert Cordingly
6
6
  Author-email: <rcording@uw.ed>
@@ -2,7 +2,7 @@ mgpsogui/__init__.py,sha256=q7AfBjeJABnFtbsZnsObpUwaXKPDVYtz46G6MKXLF74,42
2
2
  mgpsogui/mgpsogui.py,sha256=NIZmyNcbwC8EgSwf1ubdMUSJscrIEgoD4jLYziqHQ-k,148
3
3
  mgpsogui/start.yaml,sha256=ZjCVLb-MLqAxrGRm9kA7_SDpa-45EuKIELNQ2QqCAiU,4713
4
4
  mgpsogui/gui/HomePage.py,sha256=qnrbwfWKuSX6z2BEuRwLMfCe88WC55dFbBbvEe5PtFI,23626
5
- mgpsogui/gui/OptionManager.py,sha256=d-di4I9m9h0cPaKjnooTLf-QOqgIxYXbJma97EvP36I,21723
5
+ mgpsogui/gui/OptionManager.py,sha256=W--xBfiaQdeJPr5RipPcyWtK5RB81MUiQ_lJWzQK5OI,22650
6
6
  mgpsogui/gui/OptionManager_backup.py,sha256=TCWfPnHL2foN5id47jsi267lamRG6yGU6y_M29eOOJk,18530
7
7
  mgpsogui/gui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  mgpsogui/gui/General/NoticeWindow.py,sha256=HcTtaYKK4b7HognnoAHXiIHZWAXI80QfR8HM2dTLTV8,1866
@@ -11,13 +11,13 @@ mgpsogui/gui/General/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
11
11
  mgpsogui/gui/PlatformTab/PlatformTab.py,sha256=8J2Aa3Zrh1q9x07zZ0Ap9PgwHjeSKOYyj6wlxx40udw,10985
12
12
  mgpsogui/gui/PlatformTab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  mgpsogui/gui/RunTab/OptimalParameterView.py,sha256=nliUEWA840cPBQt7wjiZ-L7uBOp_ozzJhyBkL08fJzI,1752
14
- mgpsogui/gui/RunTab/RunTab.py,sha256=47_r8K-e7f8zs93_2iPYnNBzHDHZejtedk7iSElkubU,5608
14
+ mgpsogui/gui/RunTab/RunTab.py,sha256=_JWzDx5LT_uISw0Vnv-W2ypIeuKgoWqBnvFnvrLhNQA,5917
15
15
  mgpsogui/gui/RunTab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  mgpsogui/gui/SetupTab/BoundsEditorWindow.py,sha256=U64oaiDIOaimjbqKMz5rQNq2o1SrQtrRHDdTYQ9ux1s,2870
17
- mgpsogui/gui/SetupTab/BoundsList.py,sha256=UyXKujyZ3zOhgaLpICzLx-pm5RYsQOkwagZ75z9w9Hc,15204
17
+ mgpsogui/gui/SetupTab/BoundsList.py,sha256=bc1g2LLdmxkVk_Gnr-koxsxw8342IWFzpaDXu27pJD4,15231
18
18
  mgpsogui/gui/SetupTab/CustomFunctionEditorWindow.py,sha256=yx0dHSNa7fGy99Q6qFcI6j9r8p0DlV3iOBgyPMGd8pM,2884
19
19
  mgpsogui/gui/SetupTab/CustomFunctionMetrics.py,sha256=vOJpElbTgz043m6JYwe9xz_2MBHg985S6KdbJkJERW4,5923
20
- mgpsogui/gui/SetupTab/FunctionsList.py,sha256=LoHu5FESu6e_QRucNVm8tuSXLl1aLoGYd9r7WOKFTaY,7059
20
+ mgpsogui/gui/SetupTab/FunctionsList.py,sha256=6oFS8qKF3OCtxNi5aY5Rj_ovM9nv4-vh-oT_CbhVTj4,7043
21
21
  mgpsogui/gui/SetupTab/ListEditor.py,sha256=nin7Pl8z7d_yfKoAxM-yVS34uhj-LnprJ2mNRSB7Z0A,3197
22
22
  mgpsogui/gui/SetupTab/ListParametersView.py,sha256=mkGaC5cXhEOy5oD0MbTyK9z7VGZp019oK2Y8Ay-n05Q,7460
23
23
  mgpsogui/gui/SetupTab/OverrideParameterMetrics.py,sha256=rBfaSitYDOajbHvyi2TfoXAHYlz1cCt028UVpIJ_Dc0,3369
@@ -46,9 +46,9 @@ mgpsogui/gui/images/stop.png,sha256=JPuxXQerCGpLikcp7cAj3iLCOjULMYYZ2sZe0lArh68,
46
46
  mgpsogui/gui/images/test.png,sha256=MUnVpRK-isxhEHzx4Q6Yh0M6FRZD1qvgCHH2XmiSBbk,3642
47
47
  mgpsogui/gui/images/trash.png,sha256=j8cf0kWbJd-4Jp20lUVV1o1NSeQ4v1Ej4gfcIA3DVRQ,2958
48
48
  mgpsogui/gui/images/up.png,sha256=AQvFWCUqSQNaQ1E6LKZ9zNfSvW6t4mgy8uswdg9T2Hg,2457
49
- mgpsogui/gui/messages/welcome.txt,sha256=KzN_Zk3vaZeXx-G2KJmd5I7Q1_Shw62E9Fx8U4rQuUQ,5674
49
+ mgpsogui/gui/messages/welcome.txt,sha256=fPuBbYcIso3p26vpyLBK0V7FPyk7JQDhyTnVClJFttc,5984
50
50
  mgpsogui/util/GraphGenerator.py,sha256=LHHDCvBuJQ0RYQm0azi5tC-etrZ1KLQh-tkahVurPSI,31990
51
- mgpsogui/util/PSORunner.py,sha256=MjK0xlKT88Pf5vk5U--xMnWJzqZGBAOR8n6AQMaYElc,15622
51
+ mgpsogui/util/PSORunner.py,sha256=mTveURj8HGCwB5VHzvN9ELUhKtVzuynuQc8zJm4IFNs,15764
52
52
  mgpsogui/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
53
  mgpsogui/util/debug.py,sha256=Swzny9_1S-CCONWGssj9iDoSpbwu5Vr4f95g_9L8bec,19759
54
54
  mgpsogui/util/helpers.py,sha256=Ht2rge_4pGO7halz6KoLsL2eukB0k2tlkx68lBBmBA8,2669
@@ -73,8 +73,8 @@ mgpsogui/util/recosu/utils/trace_writer.py,sha256=V9BJlOjCbNYGoXGEk3CF5wjifBxvar
73
73
  mgpsogui/util/recosu/utils/utils.py,sha256=QB8vftq3142ekG0ORjz0ZBHU5YknXbR0oTsrxrPAsF0,3951
74
74
  mgpsogui/util/recosu/utils/plot/__init__.py,sha256=h1KjM7_tNDv351pcwt8A6Ibb1jhwWyx5Gbu-zj-sI3Q,71
75
75
  mgpsogui/util/recosu/utils/plot/cost_steps.py,sha256=1Ce11AJyweWkmvjXPxEygzS-h8yVLmQEDLS53yjPLqQ,3779
76
- mg_pso_gui-0.2.99.dist-info/METADATA,sha256=A2-cLJsvjJX-oVde3QyW3lqbcjo-ZTZ6PYBTg2kzvMo,9455
77
- mg_pso_gui-0.2.99.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
78
- mg_pso_gui-0.2.99.dist-info/entry_points.txt,sha256=jg82VOFjR1XDGrchs1wJSCqKYE4Ozv12aBcCSp--koA,117
79
- mg_pso_gui-0.2.99.dist-info/top_level.txt,sha256=y7JuS9xJN5YdxUsQ3PSVjN8MzQAnR146bP3ZN3PYWdE,9
80
- mg_pso_gui-0.2.99.dist-info/RECORD,,
76
+ mg_pso_gui-0.2.101.dist-info/METADATA,sha256=3cxAV5Z54FU4K9TRRsHk4HFyWdBcC9bmDxxdmRE3sw8,9456
77
+ mg_pso_gui-0.2.101.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
78
+ mg_pso_gui-0.2.101.dist-info/entry_points.txt,sha256=jg82VOFjR1XDGrchs1wJSCqKYE4Ozv12aBcCSp--koA,117
79
+ mg_pso_gui-0.2.101.dist-info/top_level.txt,sha256=y7JuS9xJN5YdxUsQ3PSVjN8MzQAnR146bP3ZN3PYWdE,9
80
+ mg_pso_gui-0.2.101.dist-info/RECORD,,
@@ -369,7 +369,33 @@ class OptionManager():
369
369
  self._project_data["name"] = file_name
370
370
 
371
371
  def copy_list(self, source_mode):
372
+ name = "backup"
373
+ index = 0
374
+ while name + str(index) in self._data:
375
+ index += 1
376
+ self._data[name + str(index)] = self._data[self._mode_sv.get()]
377
+
372
378
  self._data[self._mode_sv.get()] = self._data[source_mode]
379
+
380
+ def combine_steps(self):
381
+ mode = self._mode_sv.get()
382
+
383
+ obj = {"parameter_objects": [],
384
+ "override_parameter": [],
385
+ "objective_functions": [],
386
+ "name": sv(),
387
+ "open": True}
388
+ obj["name"].set("Combined Group")
389
+
390
+ for step in self._data[mode]["steps"]:
391
+ for param in step["parameter_objects"]:
392
+ obj["parameter_objects"].append(param)
393
+ for objective_function in step["objective_functions"]:
394
+ obj["objective_functions"].append(objective_function)
395
+ for override in step["override_parameter"]:
396
+ obj["override_parameter"].append(override)
397
+
398
+ self._data[mode]["steps"] = [obj]
373
399
 
374
400
  def get_data(self):
375
401
  return self._data[self._mode_sv.get()]
@@ -75,6 +75,10 @@ def create_tab(self, tab):
75
75
  self.option_manager.copy_list("Optimization")
76
76
  self.refresh_step_view(0)
77
77
 
78
+ def combine_steps():
79
+ self.option_manager.combine_steps()
80
+ self.refresh_step_view(0)
81
+
78
82
  def open_project_folder():
79
83
  # Open the file in the default program
80
84
  folder = self.option_manager.get_project_folder()
@@ -101,15 +105,18 @@ def create_tab(self, tab):
101
105
  self.optimization_copy = customtkinter.CTkButton(self.project_editor, text="From Optimization", command=copy_optim)
102
106
  self.optimization_copy.grid(row=4, column=0, padx=(20, 20), pady=(5, 10), sticky="ew")
103
107
 
104
- customtkinter.CTkLabel(self.project_editor, text="Project Management:").grid(row=5, column=0, padx=(20, 20), pady=(5, 10), sticky="ew")
108
+ self.combine_steps = customtkinter.CTkButton(self.project_editor, text="Combine Groups", command=combine_steps)
109
+ self.combine_steps.grid(row=5, column=0, padx=(20, 20), pady=(5, 10), sticky="ew")
110
+
111
+ customtkinter.CTkLabel(self.project_editor, text="Project Management:").grid(row=6, column=0, padx=(20, 20), pady=(5, 10), sticky="ew")
105
112
 
106
113
  self.open_folder = customtkinter.CTkButton(self.project_editor, text="Open Project Folder", command=open_project_folder)
107
- self.open_folder.grid(row=6, column=0, padx=(20, 20), pady=(5, 10), sticky="ew")
114
+ self.open_folder.grid(row=7, column=0, padx=(20, 20), pady=(5, 10), sticky="ew")
108
115
 
109
- customtkinter.CTkLabel(self.project_editor, text="Project Name:").grid(row=7, column=0, padx=(20, 20), pady=(10, 5), sticky="ew")
116
+ customtkinter.CTkLabel(self.project_editor, text="Project Name:").grid(row=8, column=0, padx=(20, 20), pady=(10, 5), sticky="ew")
110
117
  self.project_name_label = customtkinter.CTkLabel(self.project_editor, text=self.option_manager.get_project_data()["name"])
111
- self.project_name_label.grid(row=8, column=0, padx=(20, 20), pady=(5, 10), sticky="ew")
118
+ self.project_name_label.grid(row=9, column=0, padx=(20, 20), pady=(5, 10), sticky="ew")
112
119
 
113
- customtkinter.CTkLabel(self.project_editor, text="Project Path:").grid(row=9, column=0, padx=(20, 20), pady=(10, 5), sticky="ew")
120
+ customtkinter.CTkLabel(self.project_editor, text="Project Path:").grid(row=10, column=0, padx=(20, 20), pady=(10, 5), sticky="ew")
114
121
  self.project_path_label = customtkinter.CTkLabel(self.project_editor, text=self.option_manager.get_project_data()["path"])
115
- self.project_path_label.grid(row=10, column=0, padx=(20, 20), pady=(5, 10), sticky="ew")
122
+ self.project_path_label.grid(row=11, column=0, padx=(20, 20), pady=(5, 10), sticky="ew")
@@ -153,7 +153,7 @@ class BoundsList(CTkFrame):
153
153
  self.validate_number(bounds_max.get(), cc, bounds_max)
154
154
  tt2 = ctt(bounds_max, delay=0.1, alpha=0.95, message="...")
155
155
 
156
- if (bound_type == "list"):
156
+ if (bound_type == "list" and mode == "Optimization"):
157
157
  def button_click_event(bound_index):
158
158
  BEW(title="Edit List Bound", step_index=self.step_index, bound_index=bound_index, option_manager=self.option_manager)
159
159
 
@@ -54,7 +54,7 @@ class FunctionsList(CTkFrame):
54
54
 
55
55
  CTkLabel(self.containerFrame, text="Name:").grid(row=row, column=0, padx=(5, 5), pady=(5, 5), sticky="nsew")
56
56
  CTkLabel(self.containerFrame, text="Objective:").grid(row=row, column=1, padx=(5, 5), pady=(5, 5), sticky="nsew")
57
- if mode != "Sensitivity Analysis":
57
+ if mode == "Optimization":
58
58
  CTkLabel(self.containerFrame, text="Weight:").grid(row=row, column=2, padx=(5, 5), pady=(5, 5), sticky="nsew")
59
59
 
60
60
  row += 1
@@ -82,7 +82,7 @@ class FunctionsList(CTkFrame):
82
82
 
83
83
  CTkEntry(self.containerFrame, textvariable=func["name"]).grid(row=row, column=0, padx=(5, 5), pady=(5, 5), sticky="ew")
84
84
  CTkOptionMenu(self.containerFrame, values=columns, variable=func["objective_function"], command=self.refresh).grid(row=row, column=1, padx=(5, 5), pady=(5, 5), sticky="ew")
85
- if mode != "Sensitivity Analysis":
85
+ if mode == "Optimization":
86
86
  CTkEntry(self.containerFrame, textvariable=func["weight"]).grid(row=row, column=2, padx=(5, 5), pady=(5, 5), sticky="ew")
87
87
 
88
88
  row += 1
@@ -1,26 +1,28 @@
1
1
  --- Welcome to COSU Manager! ---
2
2
 
3
- To get started, it is highly recommended to open a default config file to get an example and build an understanding of how information is formatted.
3
+ COSU stands for Calibration, Optimization, Sensitivity and Uncertainty. COSU Manager is a graphical user interface built with tkinter (https://docs.python.org/3/library/tkinter.html) to execute computational services using the Cloud Services Integration Platform (CSIP; https://alm.engr.colostate.edu/cb/project/csip). The overall workflow of COSU starts with Sampling (Halton or Random), then Sensitivity Analysis, and finally Optimization using Multigroup Particle Swarm Optimization. In each of these service modes, COSU Manager is used to build service requests, read service responses, monitor service status, and display COSU results.
4
+
5
+ To get started, it is highly recommended to open a default configuration file (.json) as an example and build an understanding of how information is formatted.
4
6
 
5
7
  --- Header ---
6
8
 
7
- The header contains many important controls. To get started, click the "Load" button to load a default config and enter an HTTP endpoint to the service that you will be using. The refresh button can be used to make a connection with the service and verify that it is available. The next element of the header is the mode selector. The mode selector is one of the most important features of COSU Manager and will be used to execute an entire workflow. You will notice that whenever you switch modes the entire content of COSU Manager changes depending on which mode you are in, don't worry, data is unique to each mode and not lost which modes are switched. The overall workflow of COSU Manager starts with Sampling (Halton or Random), then next to Sensitivity Analysis, and finally Optimization using Multigroup Particle Swarm Optimization. Each of of those modes you will interact with the four main tabs of the application: Platform, Setup, Results, and Project.
9
+ The header contains many important controls. To get started, click the "Load" button to load a default config and enter an HTTP endpoint to the service that you will be using. The refresh button can be used to make a connection with the service and verify that it is available. The next element of the header is the mode selector. The mode selector is one of the most important features of COSU Manager and will be used to execute an entire workflow. You will notice that whenever you switch modes the entire content of COSU Manager changes depending on which mode you are in. Don't worry, data are unique to each mode and not lost when modes are switched. In each mode, you will interact with the four main tabs of the application: Platform, Setup, Results, and Project.
8
10
 
9
11
  --- Platform Tab ---
10
12
 
11
- The platform tab consists of 3 primary editors: Service Parameters, Service Status, and Minikube Environment Editor. The Service Parameters editor allow you to define attributes for the service such as timeouts and retry attempts. All of these parameters will be used when executing a step of the workflow and invoked at the service in the header. The Service Status editor is purely read-only and is used to view information returned from the service. This can be used to verify that the correct endpoint is being used and that the service is available. Service Status is populated whenever the refresh button in the header is clicked.
13
+ The platform tab consists of 3 primary editors: Service Parameters, Service Status, and Minikube (Kubernites) Environment Editor. The Service Parameters editor allows you to define attributes for the service such as timeouts and retry attempts. All of these parameters will be used when executing a step of the workflow and invoked at the service in the header. The Service Status editor is purely read-only and is used to view information returned from the service. This can be used to verify that the correct endpoint is being used and that the service is available. Service Status is populated whenever the refresh button in the header is clicked.
12
14
 
13
- The final editor is the Minikube Environment Editor. This tool is used to deploy a local Minikube environment of any of the workflow services. This editor can be used to start Minikube, deploy the service of the selected mode, view the status of the service, and stop Minikube. After creating the Minikube service the endpoint can be filled into the endpoint prompt in the header to use COSU Manager in the exact same way as a externally hosted service. Minikube can be used as a testing environment before creating a cloud deployment.
15
+ The final editor is the Minikube Environment Editor. This tool is used to deploy a local Minikube environment of any of the workflow services. This editor can be used to start Minikube, deploy the service of the selected mode, view the status of the service, and stop Minikube. After creating the Minikube service, the endpoint can be filled into the endpoint prompt in the header to use COSU Manager in the exact same way as an externally hosted service. Minikube can be used as a testing environment before creating a cloud deployment.
14
16
 
15
17
  --- Setup Tab ---
16
18
 
17
19
  The Setup Tab is the most advanced tab and will be used to define all of the parameters used in each of the workflow modes. In all modes, the right sidebar can be used to define Model Parameters and Hyperparameters. The values here depend on the mode, but both of these editors allow for various parameters to be defined. These editors support a variety of data types including strings, floats, integers, dates, and booleans. The editor will adapt the UI and show the appropriate editor depending on the data type (e.g. dates will have a date picker, booleans a True/False dropdown, or a textbox for strings).
18
20
 
19
- The second editor is the Group Editor. In Optimization you will be able to define multiple groups while all other modes only support a single group. The Group Editor includes options to create new groups, delete them, rearrange their order, expand/contract them, and overwrite global parameters defined in the sidebar. In each group you can define Bounds and Objective Functions. Each group has a variety of bounds and objective functions and all of their details can be defined here. Bounds can be imported from CSV files or edited in the interface. The Bounds editor will provide information about each parameter from the service in tooltips and notify when a parameter is outside the recommended bound by highlighting them in Red. In other modes besides Optimization the Setup Tab show less information, only the attributes relevant to each mode.
21
+ The second editor is the Group Editor. In Optimization you will be able to define multiple groups while all other modes only support a single group. The Group Editor includes options to create new groups, delete them, rearrange their order, expand/contract them, and overwrite global parameters defined in the sidebar. In each group you can define parameter Bounds and Objective Functions. Bounds can be imported from CSV files or edited in the interface. The Bounds editor will provide information about each parameter from the service in tooltips and notify when a parameter is outside the recommended bound by highlighting them in Red. In other modes besides Optimization the Setup Tab show less information, only the attributes relevant to each mode.
20
22
 
21
23
  --- Results Tab ---
22
24
 
23
- The Results Tab is where data can be visualized after a workflow step is ran, or view progress while Optimization is running. The main interface of the Results Tab is the left sidebar, where the figure type can be selected and then any relevant fields are displayed to edit the figure. Each mode has different figure types:
25
+ The Results Tab is where data can be visualized after a workflow step has run, or view progress while Optimization is running. The main interface of the Results Tab is the left sidebar, where the figure type can be selected and then any relevant fields are displayed to edit the figure. Each mode has different figure types:
24
26
 
25
27
  Optimization:
26
28
  - Best Cost Stacked
@@ -36,8 +38,8 @@ Sampling:
36
38
  - Sampling CSV
37
39
  - Matrix Editor
38
40
 
39
- Each of the CSV editors are the most powerful figure editors, each with extensive options to customize how the figure is generated and which dataset is being used. Figures can be generated with different themes and then Exported in a variety of formats including HTML, Plotly JSON, PDF, and PNG. If you need to more closely view a figure you can click the "Preview" option to open the graph in a web browser. While the a browser each figure has an interactive interface where the figure can be zoomed, cropped, analyzed, and exported into different formats.
41
+ Each of the CSV editors are the most powerful figure editors with extensive options to customize how the figure is generated and which dataset is being used. Figures can be generated with different themes and then Exported in a variety of formats including HTML, Plotly JSON, PDF, and PNG. If you need to view a figure more closely, you can click the "Preview" option to open the graph in a web browser. While in the a browser each figure has an interactive interface where the figure can be zoomed, cropped, analyzed, and exported into different formats.
40
42
 
41
43
  --- Project Tab ---
42
44
 
43
- The final tab is the Project Tab. This tab is likely used the least compared to all of the others. Here you can view the console output of the interface, this can be used to observe errors that are happening. In addition to that this tab also has the Project Editor. This is where you can copy data between modes. So as the workflow is built out it is expected to start with Sampling, do Sensitivity Analysis, and end with Optimization. Instead of having to setup each mode individually the parameters from one can be transferred between modes using this tab. Alongside that the Project Folder and various other project attributes can be viewed here. Finally, the Optimal Parameters found using Optimization can be viewed here.
45
+ The Project Tab is likely used the least compared to all of the others. Here you can view the console output of the interface, including any errors that are happening. This tab also has the Project Editor where you can copy data between modes. As the workflow is built out, it is expected to start with Sampling, followed by Sensitivity Analysis, and end with Optimization. Instead of having to setup each mode individually the parameters from one can be transferred between modes using the Project Tab. The Project Folder and various other project attributes can be viewed here. Finally, the Optimal Parameters found using Optimization can be viewed here.
@@ -242,6 +242,8 @@ def run_sampling(data, mode, folder, results_queue):
242
242
  process_list(data, parameter_map, args, options, oh_strategy, config, metainfo, "service_parameters")
243
243
 
244
244
  output_steps = process_steps(data)
245
+ if len(output_steps) > 1:
246
+ output_steps = [output_steps[0]]
245
247
 
246
248
  trace_file = os.path.join(folder, 'results', mode + '_trace.csv')
247
249
  file_output_mode = data["sampling_output_mode"]
@@ -385,6 +387,8 @@ def run_sensitivity_analysis(data, folder, results_queue):
385
387
  trace_path = os.path.join(folder, 'results', 'trace.csv')
386
388
 
387
389
  output_steps = process_steps(data)
390
+ if len(output_steps) > 1:
391
+ output_steps = [output_steps[0]]
388
392
 
389
393
  # Get list of parameters from steps
390
394
  parameters = []