ivoryos 0.1.9__py3-none-any.whl → 0.1.12__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.
Potentially problematic release.
This version of ivoryos might be problematic. Click here for more details.
- ivoryos/__init__.py +122 -99
- ivoryos/config.py +47 -47
- ivoryos/routes/auth/auth.py +100 -65
- ivoryos/routes/auth/templates/auth/login.html +25 -25
- ivoryos/routes/auth/templates/auth/signup.html +32 -32
- ivoryos/routes/control/control.py +400 -272
- ivoryos/routes/control/templates/control/controllers.html +75 -75
- ivoryos/routes/control/templates/control/controllers_home.html +50 -50
- ivoryos/routes/control/templates/control/controllers_new.html +89 -89
- ivoryos/routes/database/database.py +188 -114
- ivoryos/routes/database/templates/database/experiment_database.html +72 -72
- ivoryos/routes/design/design.py +543 -416
- ivoryos/routes/design/templates/design/experiment_builder.html +415 -415
- ivoryos/routes/design/templates/design/experiment_run.html +325 -325
- ivoryos/routes/main/main.py +42 -25
- ivoryos/routes/main/templates/main/help.html +141 -141
- ivoryos/routes/main/templates/main/home.html +68 -68
- ivoryos/static/.DS_Store +0 -0
- ivoryos/static/js/overlay.js +12 -12
- ivoryos/static/js/socket_handler.js +34 -34
- ivoryos/static/js/sortable_card.js +24 -24
- ivoryos/static/js/sortable_design.js +36 -36
- ivoryos/static/style.css +201 -201
- ivoryos/templates/base.html +143 -143
- ivoryos/utils/db_models.py +544 -518
- ivoryos/utils/form.py +328 -316
- ivoryos/utils/global_config.py +67 -67
- ivoryos/utils/llm_agent.py +183 -183
- ivoryos/utils/script_runner.py +166 -164
- ivoryos/utils/utils.py +437 -422
- ivoryos/version.py +1 -0
- {ivoryos-0.1.9.dist-info → ivoryos-0.1.12.dist-info}/LICENSE +21 -21
- {ivoryos-0.1.9.dist-info → ivoryos-0.1.12.dist-info}/METADATA +170 -169
- ivoryos-0.1.12.dist-info/RECORD +47 -0
- {ivoryos-0.1.9.dist-info → ivoryos-0.1.12.dist-info}/WHEEL +1 -1
- ivoryos-0.1.9.dist-info/RECORD +0 -45
- {ivoryos-0.1.9.dist-info → ivoryos-0.1.12.dist-info}/top_level.txt +0 -0
|
@@ -1,325 +1,325 @@
|
|
|
1
|
-
{% extends 'base.html' %}
|
|
2
|
-
{% block title %}IvoryOS | Design execution{% endblock %}
|
|
3
|
-
|
|
4
|
-
{% block body %}
|
|
5
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.4.1/socket.io.js"></script>
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
{% if no_deck_warning and not dismiss %}
|
|
9
|
-
{# auto pop import when there is no deck#}
|
|
10
|
-
<script type="text/javascript">
|
|
11
|
-
function OpenBootstrapPopup() {
|
|
12
|
-
$("#importModal").modal('show');
|
|
13
|
-
}
|
|
14
|
-
window.onload = function () {
|
|
15
|
-
OpenBootstrapPopup();
|
|
16
|
-
};
|
|
17
|
-
</script>
|
|
18
|
-
{% endif %}
|
|
19
|
-
|
|
20
|
-
<div class="accordion" id="accordionPanelsStayOpenExample">
|
|
21
|
-
<div class="accordion-item design-control">
|
|
22
|
-
<h2 class="accordion-header">
|
|
23
|
-
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#runpanel" aria-expanded="true" aria-controls="runpanel">
|
|
24
|
-
Run Panel
|
|
25
|
-
</button>
|
|
26
|
-
</h2>
|
|
27
|
-
<div id="runpanel" class="accordion-collapse collapse show">
|
|
28
|
-
<div class="accordion-body">
|
|
29
|
-
{% if script['script'] or script['prep'] or script['cleanup'] %}
|
|
30
|
-
<div class="row">
|
|
31
|
-
<div class="col-lg-6 col-sm-12">
|
|
32
|
-
<ul class="nav nav-tabs" id="myTabs" role="tablist">
|
|
33
|
-
<li class="nav-item" role="presentation">
|
|
34
|
-
<a class="nav-link {{ 'disabled' if config_list else '' }} {{ 'active' if not config_list else '' }}" id="tab1-tab" data-bs-toggle="tab" href="#tab1" role="tab" aria-controls="tab1" aria-selected="false">Repeat</a>
|
|
35
|
-
</li>
|
|
36
|
-
<li class="nav-item" role="presentation">
|
|
37
|
-
<a class="nav-link {{ 'disabled' if (not config_list or config_list|count > 5) else '' }} {{ 'active' if config_list and config_list|count < 6 else '' }}" id="tab4-tab" data-bs-toggle="tab" href="#tab4" role="tab" aria-controls="tab4" aria-selected="false">Quick config</a>
|
|
38
|
-
</li>
|
|
39
|
-
<li class="nav-item" role="presentation">
|
|
40
|
-
<a class="nav-link {{ 'disabled' if not config_list else '' }} {{ 'active' if config_list|count > 5 else '' }}" id="tab2-tab" data-bs-toggle="tab" href="#tab2" role="tab" aria-controls="tab2" aria-selected="false">Excel config</a>
|
|
41
|
-
</li>
|
|
42
|
-
|
|
43
|
-
<li class="nav-item" role="presentation">
|
|
44
|
-
<a class="nav-link {{ 'disabled' if not config_list or not return_list else '' }}" id="tab3-tab" data-bs-toggle="tab" href="#tab3" role="tab" aria-controls="tab3" aria-selected="false">Bayesian Optimization</a>
|
|
45
|
-
</li>
|
|
46
|
-
</ul>
|
|
47
|
-
<div class="tab-content" id="myTabsContent">
|
|
48
|
-
<div class="tab-pane fade {{ 'show active' if not config_list else '' }}" id="tab1" role="tabpanel" aria-labelledby="tab1-tab">
|
|
49
|
-
<p><h5>Control panel:</h5></p>
|
|
50
|
-
<form role="form" method='POST' name="run" action="{{url_for('design.experiment_run')}}">
|
|
51
|
-
<div class="input-group mb-3">
|
|
52
|
-
<label class="input-group-text" for="repeat">Repeat for </label>
|
|
53
|
-
<input class="form-control" type="number" id="repeat" name="repeat" min="1" max="
|
|
54
|
-
<label class="input-group-text" for="repeat"> times</label>
|
|
55
|
-
</div>
|
|
56
|
-
{# {% if not no_deck_warning%}#}
|
|
57
|
-
<div class="input-group mb-3">
|
|
58
|
-
<button class="form-control" type="submit" class="btn btn-dark">Run</button>
|
|
59
|
-
</div>
|
|
60
|
-
{# {% endif %}#}
|
|
61
|
-
</form>
|
|
62
|
-
</div>
|
|
63
|
-
<div class="tab-pane fade {{ 'show active' if config_list|count>5 else '' }}" id="tab2" role="tabpanel" aria-labelledby="tab2-tab">
|
|
64
|
-
<div>
|
|
65
|
-
|
|
66
|
-
</div>
|
|
67
|
-
<p><h5>Control with csv config:</h5></p>
|
|
68
|
-
<p>Current configure: {{ filename }}</p>
|
|
69
|
-
<div>
|
|
70
|
-
|
|
71
|
-
<form name="filenameForm" id="filenameForm" method="GET" action="{{ url_for('design.experiment_run') }}" enctype="multipart/form-data">
|
|
72
|
-
<div class="input-group mb-3">
|
|
73
|
-
<select class="form-select" name="filename" id="filenameSelect" required onchange="document.getElementById('filenameForm').submit();">
|
|
74
|
-
<option selected disabled hidden style="overflow-wrap: break-word;" value=""> -- choose config file --</option>
|
|
75
|
-
{% for config_file in config_file_list %}
|
|
76
|
-
<option {{'selected' if filename == config_file else '' }} style="overflow-wrap: break-word;" value="{{config_file}}">{{config_file}}</option>
|
|
77
|
-
{% endfor %}
|
|
78
|
-
</select>
|
|
79
|
-
</div>
|
|
80
|
-
</form>
|
|
81
|
-
|
|
82
|
-
{# <li><a class="dropdown-item" data-bs-toggle="collapse" href="#preview" role="button" aria-expanded="false">Preview config</a></li>#}
|
|
83
|
-
<a class="btn btn-primary" href="{{ url_for('design.download', filetype='configure') }}" >empty config</a>
|
|
84
|
-
<a class="btn btn-primary" data-bs-toggle="collapse" href="#loadfile" role="button" aria-expanded="false">Upload .csv</a>
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
<div class="collapse" id="loadfile" name="loadfile">
|
|
88
|
-
<form method="POST" id="loadFile" name="loadFile" action="{{ url_for('design.upload') }}" enctype="multipart/form-data">
|
|
89
|
-
<div class="input-group">
|
|
90
|
-
<input class="form-control" name="file" type="file" required="required" onchange="document.getElementById('loadFile').submit();">
|
|
91
|
-
<input class="btn btn-secondary" type="submit" value="Upload .csv">
|
|
92
|
-
</div>
|
|
93
|
-
</form>
|
|
94
|
-
</div>
|
|
95
|
-
</div>
|
|
96
|
-
|
|
97
|
-
{#Preview config file#}
|
|
98
|
-
<div id="preview">
|
|
99
|
-
{% if config_preview %}
|
|
100
|
-
<table class="table table-hover">
|
|
101
|
-
<thead>
|
|
102
|
-
<tr>
|
|
103
|
-
{% for line in config_preview[0].keys() %}
|
|
104
|
-
<th scope="col">{{ line }}</th>
|
|
105
|
-
{% endfor %}
|
|
106
|
-
</tr>
|
|
107
|
-
</thead>
|
|
108
|
-
<tbody>
|
|
109
|
-
{% for line in config_preview %}
|
|
110
|
-
<tr>
|
|
111
|
-
{% for i in line.values() %}
|
|
112
|
-
<td>{{ i }}</td>
|
|
113
|
-
{% endfor %}
|
|
114
|
-
</tr>
|
|
115
|
-
{% endfor %}
|
|
116
|
-
</tbody>
|
|
117
|
-
</table>
|
|
118
|
-
{% else %}
|
|
119
|
-
Empty config file
|
|
120
|
-
{% endif %}
|
|
121
|
-
</div>
|
|
122
|
-
{% if filename and not no_deck_warning %}
|
|
123
|
-
<form role="form" method='POST' name="run" action="{{ url_for('design.experiment_run')}}">
|
|
124
|
-
<div class="form-group">
|
|
125
|
-
<button type="submit" class="btn btn-success">Run</button>
|
|
126
|
-
</div>
|
|
127
|
-
</form>
|
|
128
|
-
{% endif %}
|
|
129
|
-
</div>
|
|
130
|
-
|
|
131
|
-
<div class="tab-pane fade " id="tab3" role="tabpanel" aria-labelledby="tab3-tab">
|
|
132
|
-
<form role="form" method='POST' name="bo" action="{{ url_for('design.experiment_run')}}">
|
|
133
|
-
<div class="form-group">
|
|
134
|
-
<p><h5>Parameters:</h5><p>
|
|
135
|
-
{% for config in config_list %}
|
|
136
|
-
<div class="row g-3 align-items-center">
|
|
137
|
-
<div class="col-lg-3 col-sm-6 ">
|
|
138
|
-
{{config}}:
|
|
139
|
-
</div>
|
|
140
|
-
{# <div class="col-auto">#}
|
|
141
|
-
{# <label class="col-form-label" for="{{config}}_type">Type</label>#}
|
|
142
|
-
{# </div>#}
|
|
143
|
-
<div class="col-auto">
|
|
144
|
-
<select class="form-select" id="{{config}}_type" name="{{config}}_type">
|
|
145
|
-
<option selected value="range">range</option>
|
|
146
|
-
<option value="choice">choice</option>
|
|
147
|
-
<option value="fixed">fixed</option>
|
|
148
|
-
</select>
|
|
149
|
-
</div>
|
|
150
|
-
<div class="col-auto">
|
|
151
|
-
<label class="" for="{{config}}_value">Values</label>
|
|
152
|
-
</div>
|
|
153
|
-
<div class="col-auto">
|
|
154
|
-
<input type="text" class="form-control" id="{{config}}_value" name="{{config}}_value" placeholder="1, 2, 3">
|
|
155
|
-
</div>
|
|
156
|
-
{# <div class="col-auto">#}
|
|
157
|
-
{# <input type="text" class="form-control" id="{{config}}_value_max" style="display: none;" placeholder="1, 2, 3">#}
|
|
158
|
-
{# </div>#}
|
|
159
|
-
</div>
|
|
160
|
-
{% endfor %}
|
|
161
|
-
<p><h5>Objective:</h5><p>
|
|
162
|
-
{% for objective in return_list %}
|
|
163
|
-
<div class="row gy-2 gx-3 align-items-center input-group">
|
|
164
|
-
<div class="col-3">
|
|
165
|
-
{{objective}}:
|
|
166
|
-
</div>
|
|
167
|
-
{# <div class="col-auto">#}
|
|
168
|
-
{# <label class="" for="{{objective}}_min">Minimize</label>#}
|
|
169
|
-
{# </div>#}
|
|
170
|
-
<div class="col-auto">
|
|
171
|
-
<select class="form-select" id="{{objective}}_min" name="{{objective}}_min">
|
|
172
|
-
<option selected>minimize</option>
|
|
173
|
-
<option>maximize</option>
|
|
174
|
-
<option>none</option>
|
|
175
|
-
</select>
|
|
176
|
-
</div>
|
|
177
|
-
{# <div class="col-auto">#}
|
|
178
|
-
{# <label class="" for="{{objective}}_threshold">Threshold</label>#}
|
|
179
|
-
{# </div>#}
|
|
180
|
-
{# <div class="col-auto">#}
|
|
181
|
-
{# <input type="text" class="form-control" id="{{objective}}_threshold" name="{{objective}}_threshold" placeholder="None">#}
|
|
182
|
-
{# </div>#}
|
|
183
|
-
</div>
|
|
184
|
-
{% endfor %}
|
|
185
|
-
<p><h5>Budget:</h5></p>
|
|
186
|
-
<div class="input-group mb-3">
|
|
187
|
-
<label class="input-group-text" for="repeat">Max iteration </label>
|
|
188
|
-
<input class="form-control" type="number" id="repeat" name="repeat" min="1" max="
|
|
189
|
-
</div>
|
|
190
|
-
{% if not no_deck_warning%}
|
|
191
|
-
<div class="input-group mb-3">
|
|
192
|
-
<button class="form-control" type="submit" name="bo">Run</button>
|
|
193
|
-
</div>
|
|
194
|
-
{% endif %}
|
|
195
|
-
</div>
|
|
196
|
-
</form>
|
|
197
|
-
</div>
|
|
198
|
-
<div class="tab-pane fade {{ 'show active' if config_list and config_list|count<=5 else '' }}" id="tab4" role="tabpanel" aria-labelledby="tab4-tab">
|
|
199
|
-
<p><h5>Control panel:</h5></p>
|
|
200
|
-
<div>
|
|
201
|
-
<form method="POST" name="online-config" id="online-config" action="{{url_for('design.experiment_run')}}">
|
|
202
|
-
<table id="dataInputTable" class="table table-striped">
|
|
203
|
-
<thead class="thead-dark">
|
|
204
|
-
<tr>
|
|
205
|
-
{% for column in config_list %}
|
|
206
|
-
<th>{{ column }}</th>
|
|
207
|
-
{% endfor %}
|
|
208
|
-
</tr>
|
|
209
|
-
</thead>
|
|
210
|
-
<tbody>
|
|
211
|
-
</tbody>
|
|
212
|
-
</table>
|
|
213
|
-
<div class="btn btn-light" onclick="addRow()"><i class="bi bi-plus-circle" ></i></div>
|
|
214
|
-
<button type="submit" name="online-config" class="btn btn-success">Run</button>
|
|
215
|
-
</form>
|
|
216
|
-
</div>
|
|
217
|
-
</div>
|
|
218
|
-
</div>
|
|
219
|
-
</div>
|
|
220
|
-
<div class="col-lg-6 col-sm-12 logging-panel">
|
|
221
|
-
<p>
|
|
222
|
-
<div class="p d-flex justify-content-between align-items-center">
|
|
223
|
-
<h5>Progress:</h5>
|
|
224
|
-
<button id="abort" class="btn btn-danger ">Abort Pending Actions</button>
|
|
225
|
-
</div>
|
|
226
|
-
</p>
|
|
227
|
-
<div class="progress" role="progressbar" aria-label="Animated striped example" aria-valuenow="10" aria-valuemin="0" aria-valuemax="100">
|
|
228
|
-
<div id="progress-bar-inner" class="progress-bar progress-bar-striped progress-bar-animated"></div>
|
|
229
|
-
</div>
|
|
230
|
-
<p><h5>Log:</h5></p>
|
|
231
|
-
<div id="logging-panel"></div>
|
|
232
|
-
</div>
|
|
233
|
-
</div>
|
|
234
|
-
{% endif %}
|
|
235
|
-
</div>
|
|
236
|
-
</div>
|
|
237
|
-
</div>
|
|
238
|
-
<div class="accordion-item design-control">
|
|
239
|
-
<h2 class="accordion-header">
|
|
240
|
-
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#data" aria-expanded="false" aria-controls="script">
|
|
241
|
-
Download experiment data csv
|
|
242
|
-
</button>
|
|
243
|
-
</h2>
|
|
244
|
-
<div id="data" class="accordion-collapse collapse">
|
|
245
|
-
<div class="accordion-body">
|
|
246
|
-
{% if session["most_recent_result"] %}
|
|
247
|
-
<p><a href="{{ url_for('design.download_results', filename=session["most_recent_result"]) }}">Download the latest data <i class="bi bi-download"></i></a></p>
|
|
248
|
-
{% endif %}
|
|
249
|
-
<p>
|
|
250
|
-
<h5>All data files</h5>
|
|
251
|
-
{% for datafile in data_list %}
|
|
252
|
-
<div>
|
|
253
|
-
{{ datafile }} <a href="{{ url_for('design.download_results', filename=datafile) }} "><i class="bi bi-download"></i></a>
|
|
254
|
-
</div>
|
|
255
|
-
{% endfor %}
|
|
256
|
-
</p>
|
|
257
|
-
</div>
|
|
258
|
-
</div>
|
|
259
|
-
</div>
|
|
260
|
-
<div class="accordion-item design-control">
|
|
261
|
-
<h2 class="accordion-header">
|
|
262
|
-
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#script" aria-expanded="false" aria-controls="script">
|
|
263
|
-
Script
|
|
264
|
-
</button>
|
|
265
|
-
</h2>
|
|
266
|
-
<div id="script" class="accordion-collapse collapse">
|
|
267
|
-
<div class="accordion-body">
|
|
268
|
-
{% set labels = {
|
|
269
|
-
'prep': 'Preparation:',
|
|
270
|
-
'script': 'Experiment:',
|
|
271
|
-
'cleanup': 'Clean up:'
|
|
272
|
-
} %}
|
|
273
|
-
{% for key, buttons in design_buttons.items() %}
|
|
274
|
-
{% if buttons %}
|
|
275
|
-
<h6>
|
|
276
|
-
{{labels[key]}}
|
|
277
|
-
</h6>
|
|
278
|
-
<ul>
|
|
279
|
-
{% for button in buttons %}
|
|
280
|
-
<li id="{{ button['id'] }}" style="list-style-type: none;">
|
|
281
|
-
<button type="button" class="btn btn-light" style="{{ button['style'] }}">{{ button['label'] }}</button>
|
|
282
|
-
</li>
|
|
283
|
-
{% endfor %}
|
|
284
|
-
</ul>
|
|
285
|
-
{% endif %}
|
|
286
|
-
{% endfor %}
|
|
287
|
-
</div>
|
|
288
|
-
</div>
|
|
289
|
-
</div>
|
|
290
|
-
<div class="accordion-item design-control">
|
|
291
|
-
<h2 class="accordion-header">
|
|
292
|
-
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#python" aria-expanded="false" aria-controls="python">
|
|
293
|
-
Python Script
|
|
294
|
-
</button>
|
|
295
|
-
</h2>
|
|
296
|
-
<div id="python" class="accordion-collapse collapse">
|
|
297
|
-
<div class="accordion-body">
|
|
298
|
-
<pre><code class="python" >{{dot_py}}</code></pre>
|
|
299
|
-
<a href="{{ url_for('design.download', filetype='python') }}">Download <i class="bi bi-download"></i></a>
|
|
300
|
-
</div>
|
|
301
|
-
</div>
|
|
302
|
-
</div>
|
|
303
|
-
</div>
|
|
304
|
-
<script src="{{ url_for('static', filename='js/socket_handler.js') }}"></script>
|
|
305
|
-
<script>
|
|
306
|
-
var rowCount = 0; // Initialize row count
|
|
307
|
-
function addRow() {
|
|
308
|
-
rowCount++; // Increment row count each time a row is added
|
|
309
|
-
var table = document.getElementById("dataInputTable");
|
|
310
|
-
var newRow = table.insertRow(-1); // Adds a row at the end of the table
|
|
311
|
-
{% for column, type in config_type_list.items() %}
|
|
312
|
-
var cell = newRow.insertCell(-1);
|
|
313
|
-
cell.innerHTML = '<input type="text" class="form-control" name="{{ column }}[' + rowCount + ']" placeholder={{ type }}>';
|
|
314
|
-
{% endfor %}
|
|
315
|
-
}
|
|
316
|
-
</script>
|
|
317
|
-
<script>
|
|
318
|
-
// Initially add 5 rows when the page loads
|
|
319
|
-
document.addEventListener("DOMContentLoaded", function() {
|
|
320
|
-
for (let i = 0; i < 5; i++) {
|
|
321
|
-
addRow();
|
|
322
|
-
}
|
|
323
|
-
});
|
|
324
|
-
</script>
|
|
325
|
-
{% endblock %}
|
|
1
|
+
{% extends 'base.html' %}
|
|
2
|
+
{% block title %}IvoryOS | Design execution{% endblock %}
|
|
3
|
+
|
|
4
|
+
{% block body %}
|
|
5
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.4.1/socket.io.js"></script>
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
{% if no_deck_warning and not dismiss %}
|
|
9
|
+
{# auto pop import when there is no deck#}
|
|
10
|
+
<script type="text/javascript">
|
|
11
|
+
function OpenBootstrapPopup() {
|
|
12
|
+
$("#importModal").modal('show');
|
|
13
|
+
}
|
|
14
|
+
window.onload = function () {
|
|
15
|
+
OpenBootstrapPopup();
|
|
16
|
+
};
|
|
17
|
+
</script>
|
|
18
|
+
{% endif %}
|
|
19
|
+
|
|
20
|
+
<div class="accordion" id="accordionPanelsStayOpenExample">
|
|
21
|
+
<div class="accordion-item design-control">
|
|
22
|
+
<h2 class="accordion-header">
|
|
23
|
+
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#runpanel" aria-expanded="true" aria-controls="runpanel">
|
|
24
|
+
Run Panel
|
|
25
|
+
</button>
|
|
26
|
+
</h2>
|
|
27
|
+
<div id="runpanel" class="accordion-collapse collapse show">
|
|
28
|
+
<div class="accordion-body">
|
|
29
|
+
{% if script['script'] or script['prep'] or script['cleanup'] %}
|
|
30
|
+
<div class="row">
|
|
31
|
+
<div class="col-lg-6 col-sm-12">
|
|
32
|
+
<ul class="nav nav-tabs" id="myTabs" role="tablist">
|
|
33
|
+
<li class="nav-item" role="presentation">
|
|
34
|
+
<a class="nav-link {{ 'disabled' if config_list else '' }} {{ 'active' if not config_list else '' }}" id="tab1-tab" data-bs-toggle="tab" href="#tab1" role="tab" aria-controls="tab1" aria-selected="false">Repeat</a>
|
|
35
|
+
</li>
|
|
36
|
+
<li class="nav-item" role="presentation">
|
|
37
|
+
<a class="nav-link {{ 'disabled' if (not config_list or config_list|count > 5) else '' }} {{ 'active' if config_list and config_list|count < 6 else '' }}" id="tab4-tab" data-bs-toggle="tab" href="#tab4" role="tab" aria-controls="tab4" aria-selected="false">Quick config</a>
|
|
38
|
+
</li>
|
|
39
|
+
<li class="nav-item" role="presentation">
|
|
40
|
+
<a class="nav-link {{ 'disabled' if not config_list else '' }} {{ 'active' if config_list|count > 5 else '' }}" id="tab2-tab" data-bs-toggle="tab" href="#tab2" role="tab" aria-controls="tab2" aria-selected="false">Excel config</a>
|
|
41
|
+
</li>
|
|
42
|
+
|
|
43
|
+
<li class="nav-item" role="presentation">
|
|
44
|
+
<a class="nav-link {{ 'disabled' if not config_list or not return_list else '' }}" id="tab3-tab" data-bs-toggle="tab" href="#tab3" role="tab" aria-controls="tab3" aria-selected="false">Bayesian Optimization</a>
|
|
45
|
+
</li>
|
|
46
|
+
</ul>
|
|
47
|
+
<div class="tab-content" id="myTabsContent">
|
|
48
|
+
<div class="tab-pane fade {{ 'show active' if not config_list else '' }}" id="tab1" role="tabpanel" aria-labelledby="tab1-tab">
|
|
49
|
+
<p><h5>Control panel:</h5></p>
|
|
50
|
+
<form role="form" method='POST' name="run" action="{{url_for('design.experiment_run')}}">
|
|
51
|
+
<div class="input-group mb-3">
|
|
52
|
+
<label class="input-group-text" for="repeat">Repeat for </label>
|
|
53
|
+
<input class="form-control" type="number" id="repeat" name="repeat" min="1" max="1000" value="1">
|
|
54
|
+
<label class="input-group-text" for="repeat"> times</label>
|
|
55
|
+
</div>
|
|
56
|
+
{# {% if not no_deck_warning%}#}
|
|
57
|
+
<div class="input-group mb-3">
|
|
58
|
+
<button class="form-control" type="submit" class="btn btn-dark">Run</button>
|
|
59
|
+
</div>
|
|
60
|
+
{# {% endif %}#}
|
|
61
|
+
</form>
|
|
62
|
+
</div>
|
|
63
|
+
<div class="tab-pane fade {{ 'show active' if config_list|count>5 else '' }}" id="tab2" role="tabpanel" aria-labelledby="tab2-tab">
|
|
64
|
+
<div>
|
|
65
|
+
|
|
66
|
+
</div>
|
|
67
|
+
<p><h5>Control with csv config:</h5></p>
|
|
68
|
+
<p>Current configure: {{ filename }}</p>
|
|
69
|
+
<div>
|
|
70
|
+
|
|
71
|
+
<form name="filenameForm" id="filenameForm" method="GET" action="{{ url_for('design.experiment_run') }}" enctype="multipart/form-data">
|
|
72
|
+
<div class="input-group mb-3">
|
|
73
|
+
<select class="form-select" name="filename" id="filenameSelect" required onchange="document.getElementById('filenameForm').submit();">
|
|
74
|
+
<option selected disabled hidden style="overflow-wrap: break-word;" value=""> -- choose config file --</option>
|
|
75
|
+
{% for config_file in config_file_list %}
|
|
76
|
+
<option {{'selected' if filename == config_file else '' }} style="overflow-wrap: break-word;" value="{{config_file}}">{{config_file}}</option>
|
|
77
|
+
{% endfor %}
|
|
78
|
+
</select>
|
|
79
|
+
</div>
|
|
80
|
+
</form>
|
|
81
|
+
|
|
82
|
+
{# <li><a class="dropdown-item" data-bs-toggle="collapse" href="#preview" role="button" aria-expanded="false">Preview config</a></li>#}
|
|
83
|
+
<a class="btn btn-primary" href="{{ url_for('design.download', filetype='configure') }}" >empty config</a>
|
|
84
|
+
<a class="btn btn-primary" data-bs-toggle="collapse" href="#loadfile" role="button" aria-expanded="false">Upload .csv</a>
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
<div class="collapse" id="loadfile" name="loadfile">
|
|
88
|
+
<form method="POST" id="loadFile" name="loadFile" action="{{ url_for('design.upload') }}" enctype="multipart/form-data">
|
|
89
|
+
<div class="input-group">
|
|
90
|
+
<input class="form-control" name="file" type="file" required="required" onchange="document.getElementById('loadFile').submit();">
|
|
91
|
+
<input class="btn btn-secondary" type="submit" value="Upload .csv">
|
|
92
|
+
</div>
|
|
93
|
+
</form>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
{#Preview config file#}
|
|
98
|
+
<div id="preview">
|
|
99
|
+
{% if config_preview %}
|
|
100
|
+
<table class="table table-hover">
|
|
101
|
+
<thead>
|
|
102
|
+
<tr>
|
|
103
|
+
{% for line in config_preview[0].keys() %}
|
|
104
|
+
<th scope="col">{{ line }}</th>
|
|
105
|
+
{% endfor %}
|
|
106
|
+
</tr>
|
|
107
|
+
</thead>
|
|
108
|
+
<tbody>
|
|
109
|
+
{% for line in config_preview %}
|
|
110
|
+
<tr>
|
|
111
|
+
{% for i in line.values() %}
|
|
112
|
+
<td>{{ i }}</td>
|
|
113
|
+
{% endfor %}
|
|
114
|
+
</tr>
|
|
115
|
+
{% endfor %}
|
|
116
|
+
</tbody>
|
|
117
|
+
</table>
|
|
118
|
+
{% else %}
|
|
119
|
+
Empty config file
|
|
120
|
+
{% endif %}
|
|
121
|
+
</div>
|
|
122
|
+
{% if filename and not no_deck_warning %}
|
|
123
|
+
<form role="form" method='POST' name="run" action="{{ url_for('design.experiment_run')}}">
|
|
124
|
+
<div class="form-group">
|
|
125
|
+
<button type="submit" class="btn btn-success">Run</button>
|
|
126
|
+
</div>
|
|
127
|
+
</form>
|
|
128
|
+
{% endif %}
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
<div class="tab-pane fade " id="tab3" role="tabpanel" aria-labelledby="tab3-tab">
|
|
132
|
+
<form role="form" method='POST' name="bo" action="{{ url_for('design.experiment_run')}}">
|
|
133
|
+
<div class="form-group">
|
|
134
|
+
<p><h5>Parameters:</h5><p>
|
|
135
|
+
{% for config in config_list %}
|
|
136
|
+
<div class="row g-3 align-items-center">
|
|
137
|
+
<div class="col-lg-3 col-sm-6 ">
|
|
138
|
+
{{config}}:
|
|
139
|
+
</div>
|
|
140
|
+
{# <div class="col-auto">#}
|
|
141
|
+
{# <label class="col-form-label" for="{{config}}_type">Type</label>#}
|
|
142
|
+
{# </div>#}
|
|
143
|
+
<div class="col-auto">
|
|
144
|
+
<select class="form-select" id="{{config}}_type" name="{{config}}_type">
|
|
145
|
+
<option selected value="range">range</option>
|
|
146
|
+
<option value="choice">choice</option>
|
|
147
|
+
<option value="fixed">fixed</option>
|
|
148
|
+
</select>
|
|
149
|
+
</div>
|
|
150
|
+
<div class="col-auto">
|
|
151
|
+
<label class="" for="{{config}}_value">Values</label>
|
|
152
|
+
</div>
|
|
153
|
+
<div class="col-auto">
|
|
154
|
+
<input type="text" class="form-control" id="{{config}}_value" name="{{config}}_value" placeholder="1, 2, 3">
|
|
155
|
+
</div>
|
|
156
|
+
{# <div class="col-auto">#}
|
|
157
|
+
{# <input type="text" class="form-control" id="{{config}}_value_max" style="display: none;" placeholder="1, 2, 3">#}
|
|
158
|
+
{# </div>#}
|
|
159
|
+
</div>
|
|
160
|
+
{% endfor %}
|
|
161
|
+
<p><h5>Objective:</h5><p>
|
|
162
|
+
{% for objective in return_list %}
|
|
163
|
+
<div class="row gy-2 gx-3 align-items-center input-group">
|
|
164
|
+
<div class="col-3">
|
|
165
|
+
{{objective}}:
|
|
166
|
+
</div>
|
|
167
|
+
{# <div class="col-auto">#}
|
|
168
|
+
{# <label class="" for="{{objective}}_min">Minimize</label>#}
|
|
169
|
+
{# </div>#}
|
|
170
|
+
<div class="col-auto">
|
|
171
|
+
<select class="form-select" id="{{objective}}_min" name="{{objective}}_min">
|
|
172
|
+
<option selected>minimize</option>
|
|
173
|
+
<option>maximize</option>
|
|
174
|
+
<option>none</option>
|
|
175
|
+
</select>
|
|
176
|
+
</div>
|
|
177
|
+
{# <div class="col-auto">#}
|
|
178
|
+
{# <label class="" for="{{objective}}_threshold">Threshold</label>#}
|
|
179
|
+
{# </div>#}
|
|
180
|
+
{# <div class="col-auto">#}
|
|
181
|
+
{# <input type="text" class="form-control" id="{{objective}}_threshold" name="{{objective}}_threshold" placeholder="None">#}
|
|
182
|
+
{# </div>#}
|
|
183
|
+
</div>
|
|
184
|
+
{% endfor %}
|
|
185
|
+
<p><h5>Budget:</h5></p>
|
|
186
|
+
<div class="input-group mb-3">
|
|
187
|
+
<label class="input-group-text" for="repeat">Max iteration </label>
|
|
188
|
+
<input class="form-control" type="number" id="repeat" name="repeat" min="1" max="1000" value="25">
|
|
189
|
+
</div>
|
|
190
|
+
{% if not no_deck_warning%}
|
|
191
|
+
<div class="input-group mb-3">
|
|
192
|
+
<button class="form-control" type="submit" name="bo">Run</button>
|
|
193
|
+
</div>
|
|
194
|
+
{% endif %}
|
|
195
|
+
</div>
|
|
196
|
+
</form>
|
|
197
|
+
</div>
|
|
198
|
+
<div class="tab-pane fade {{ 'show active' if config_list and config_list|count<=5 else '' }}" id="tab4" role="tabpanel" aria-labelledby="tab4-tab">
|
|
199
|
+
<p><h5>Control panel:</h5></p>
|
|
200
|
+
<div>
|
|
201
|
+
<form method="POST" name="online-config" id="online-config" action="{{url_for('design.experiment_run')}}">
|
|
202
|
+
<table id="dataInputTable" class="table table-striped">
|
|
203
|
+
<thead class="thead-dark">
|
|
204
|
+
<tr>
|
|
205
|
+
{% for column in config_list %}
|
|
206
|
+
<th>{{ column }}</th>
|
|
207
|
+
{% endfor %}
|
|
208
|
+
</tr>
|
|
209
|
+
</thead>
|
|
210
|
+
<tbody>
|
|
211
|
+
</tbody>
|
|
212
|
+
</table>
|
|
213
|
+
<div class="btn btn-light" onclick="addRow()"><i class="bi bi-plus-circle" ></i></div>
|
|
214
|
+
<button type="submit" name="online-config" class="btn btn-success">Run</button>
|
|
215
|
+
</form>
|
|
216
|
+
</div>
|
|
217
|
+
</div>
|
|
218
|
+
</div>
|
|
219
|
+
</div>
|
|
220
|
+
<div class="col-lg-6 col-sm-12 logging-panel">
|
|
221
|
+
<p>
|
|
222
|
+
<div class="p d-flex justify-content-between align-items-center">
|
|
223
|
+
<h5>Progress:</h5>
|
|
224
|
+
<button id="abort" class="btn btn-danger ">Abort Pending Actions</button>
|
|
225
|
+
</div>
|
|
226
|
+
</p>
|
|
227
|
+
<div class="progress" role="progressbar" aria-label="Animated striped example" aria-valuenow="10" aria-valuemin="0" aria-valuemax="100">
|
|
228
|
+
<div id="progress-bar-inner" class="progress-bar progress-bar-striped progress-bar-animated"></div>
|
|
229
|
+
</div>
|
|
230
|
+
<p><h5>Log:</h5></p>
|
|
231
|
+
<div id="logging-panel"></div>
|
|
232
|
+
</div>
|
|
233
|
+
</div>
|
|
234
|
+
{% endif %}
|
|
235
|
+
</div>
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
<div class="accordion-item design-control">
|
|
239
|
+
<h2 class="accordion-header">
|
|
240
|
+
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#data" aria-expanded="false" aria-controls="script">
|
|
241
|
+
Download experiment data csv
|
|
242
|
+
</button>
|
|
243
|
+
</h2>
|
|
244
|
+
<div id="data" class="accordion-collapse collapse">
|
|
245
|
+
<div class="accordion-body">
|
|
246
|
+
{% if session["most_recent_result"] %}
|
|
247
|
+
<p><a href="{{ url_for('design.download_results', filename=session["most_recent_result"]) }}">Download the latest data <i class="bi bi-download"></i></a></p>
|
|
248
|
+
{% endif %}
|
|
249
|
+
<p>
|
|
250
|
+
<h5>All data files</h5>
|
|
251
|
+
{% for datafile in data_list %}
|
|
252
|
+
<div>
|
|
253
|
+
{{ datafile }} <a href="{{ url_for('design.download_results', filename=datafile) }} "><i class="bi bi-download"></i></a>
|
|
254
|
+
</div>
|
|
255
|
+
{% endfor %}
|
|
256
|
+
</p>
|
|
257
|
+
</div>
|
|
258
|
+
</div>
|
|
259
|
+
</div>
|
|
260
|
+
<div class="accordion-item design-control">
|
|
261
|
+
<h2 class="accordion-header">
|
|
262
|
+
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#script" aria-expanded="false" aria-controls="script">
|
|
263
|
+
Script
|
|
264
|
+
</button>
|
|
265
|
+
</h2>
|
|
266
|
+
<div id="script" class="accordion-collapse collapse">
|
|
267
|
+
<div class="accordion-body">
|
|
268
|
+
{% set labels = {
|
|
269
|
+
'prep': 'Preparation:',
|
|
270
|
+
'script': 'Experiment:',
|
|
271
|
+
'cleanup': 'Clean up:'
|
|
272
|
+
} %}
|
|
273
|
+
{% for key, buttons in design_buttons.items() %}
|
|
274
|
+
{% if buttons %}
|
|
275
|
+
<h6>
|
|
276
|
+
{{labels[key]}}
|
|
277
|
+
</h6>
|
|
278
|
+
<ul>
|
|
279
|
+
{% for button in buttons %}
|
|
280
|
+
<li id="{{ button['id'] }}" style="list-style-type: none;">
|
|
281
|
+
<button type="button" class="btn btn-light" style="{{ button['style'] }}">{{ button['label'] }}</button>
|
|
282
|
+
</li>
|
|
283
|
+
{% endfor %}
|
|
284
|
+
</ul>
|
|
285
|
+
{% endif %}
|
|
286
|
+
{% endfor %}
|
|
287
|
+
</div>
|
|
288
|
+
</div>
|
|
289
|
+
</div>
|
|
290
|
+
<div class="accordion-item design-control">
|
|
291
|
+
<h2 class="accordion-header">
|
|
292
|
+
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#python" aria-expanded="false" aria-controls="python">
|
|
293
|
+
Python Script
|
|
294
|
+
</button>
|
|
295
|
+
</h2>
|
|
296
|
+
<div id="python" class="accordion-collapse collapse">
|
|
297
|
+
<div class="accordion-body">
|
|
298
|
+
<pre><code class="python" >{{dot_py}}</code></pre>
|
|
299
|
+
<a href="{{ url_for('design.download', filetype='python') }}">Download <i class="bi bi-download"></i></a>
|
|
300
|
+
</div>
|
|
301
|
+
</div>
|
|
302
|
+
</div>
|
|
303
|
+
</div>
|
|
304
|
+
<script src="{{ url_for('static', filename='js/socket_handler.js') }}"></script>
|
|
305
|
+
<script>
|
|
306
|
+
var rowCount = 0; // Initialize row count
|
|
307
|
+
function addRow() {
|
|
308
|
+
rowCount++; // Increment row count each time a row is added
|
|
309
|
+
var table = document.getElementById("dataInputTable");
|
|
310
|
+
var newRow = table.insertRow(-1); // Adds a row at the end of the table
|
|
311
|
+
{% for column, type in config_type_list.items() %}
|
|
312
|
+
var cell = newRow.insertCell(-1);
|
|
313
|
+
cell.innerHTML = '<input type="text" class="form-control" name="{{ column }}[' + rowCount + ']" placeholder={{ type }}>';
|
|
314
|
+
{% endfor %}
|
|
315
|
+
}
|
|
316
|
+
</script>
|
|
317
|
+
<script>
|
|
318
|
+
// Initially add 5 rows when the page loads
|
|
319
|
+
document.addEventListener("DOMContentLoaded", function() {
|
|
320
|
+
for (let i = 0; i < 5; i++) {
|
|
321
|
+
addRow();
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
</script>
|
|
325
|
+
{% endblock %}
|