pico-ml 2.0.0__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.
- pico/__init__.py +3 -0
- pico/__main__.py +3 -0
- pico/cli/__init__.py +2 -0
- pico/cli/main.py +117 -0
- pico/conf/SupportedCV.py +17 -0
- pico/conf/SupportedModels.py +73 -0
- pico/conf/algo_sklearn.json +51 -0
- pico/conf/parameters.py +14 -0
- pico/domain/ClassificationDesign.py +107 -0
- pico/domain/Controller.py +397 -0
- pico/domain/DataMatrix.py +147 -0
- pico/domain/ExperimentDTO.py +17 -0
- pico/domain/MetaData.py +229 -0
- pico/domain/MetaboExperiment.py +696 -0
- pico/domain/MetaboModel.py +53 -0
- pico/domain/ModelFactory.py +45 -0
- pico/domain/Results.py +602 -0
- pico/domain/SplitGroup.py +202 -0
- pico/domain/__init__.py +9 -0
- pico/domain/dumps/metadata/.gitkeep +0 -0
- pico/domain/dumps/splits/.gitkeep +0 -0
- pico/service/DataFormat.py +180 -0
- pico/service/ExperimentDesign.py +30 -0
- pico/service/LoggerConfig.py +150 -0
- pico/service/Plots.py +472 -0
- pico/service/RunMLalgo.py +93 -0
- pico/service/SamplesPairing.py +390 -0
- pico/service/Utils.py +497 -0
- pico/service/__init__.py +7 -0
- pico/ui/__init__.py +1 -0
- pico/ui/app.py +145 -0
- pico/ui/assets/000_Stylesheet.css +464 -0
- pico/ui/assets/DecisionTree.png +0 -0
- pico/ui/assets/Figure_home_wider.png +0 -0
- pico/ui/assets/favicon.ico +0 -0
- pico/ui/assets/help_icon.png +0 -0
- pico/ui/assets/help_icon.svg +15 -0
- pico/ui/assets/update_figure_steps_MeDIC_4.svg +1 -0
- pico/ui/tabs/AggregatedResultsTab.py +394 -0
- pico/ui/tabs/InfoTab.py +440 -0
- pico/ui/tabs/InterpretTab.py +21 -0
- pico/ui/tabs/MLTab.py +487 -0
- pico/ui/tabs/MetaTab.py +23 -0
- pico/ui/tabs/ResultsTab.py +1062 -0
- pico/ui/tabs/SplitsTab.py +1227 -0
- pico/ui/tabs/__init__.py +6 -0
- pico/ui/tabs/utils.py +101 -0
- pico_ml-2.0.0.dist-info/METADATA +86 -0
- pico_ml-2.0.0.dist-info/RECORD +52 -0
- pico_ml-2.0.0.dist-info/WHEEL +4 -0
- pico_ml-2.0.0.dist-info/entry_points.txt +2 -0
- pico_ml-2.0.0.dist-info/licenses/LICENSE +437 -0
pico/ui/tabs/MLTab.py
ADDED
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import re
|
|
3
|
+
|
|
4
|
+
import dash_bootstrap_components as dbc
|
|
5
|
+
import pandas as pd
|
|
6
|
+
from dash import html, State, Input, Output, dash, dcc, callback_context, ALL
|
|
7
|
+
from os.path import basename
|
|
8
|
+
|
|
9
|
+
from .MetaTab import MetaTab
|
|
10
|
+
from ...service import Utils, init_logger, log_exceptions
|
|
11
|
+
from ...domain import Controller
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class MLTab(MetaTab):
|
|
15
|
+
def __init__(self, app: dash.Dash, metabo_controller: Controller):
|
|
16
|
+
super().__init__(app, metabo_controller)
|
|
17
|
+
self._logger = init_logger()
|
|
18
|
+
|
|
19
|
+
def getLayout(self) -> dbc.Tab:
|
|
20
|
+
__splitConfigFile = html.Div(
|
|
21
|
+
[
|
|
22
|
+
dbc.Label("Select CV search type", className="form_labels"),
|
|
23
|
+
dbc.RadioItems(
|
|
24
|
+
options=Utils.format_list_for_checklist(
|
|
25
|
+
self.metabo_controller.get_cv_types()
|
|
26
|
+
),
|
|
27
|
+
value=self.metabo_controller.get_selected_cv_type(),
|
|
28
|
+
id="radio_cv_types",
|
|
29
|
+
),
|
|
30
|
+
html.Br(),
|
|
31
|
+
html.Div(id="cv_params"),
|
|
32
|
+
],
|
|
33
|
+
className="form_field",
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
__ThreadingConfig = html.Div(
|
|
37
|
+
[
|
|
38
|
+
dbc.Label("Multi-threading activation", className="form_labels"),
|
|
39
|
+
dbc.Checklist(
|
|
40
|
+
options=[
|
|
41
|
+
{"label": "Multi-threading is off", "value": 1},
|
|
42
|
+
],
|
|
43
|
+
id="switches-input",
|
|
44
|
+
value=[1],
|
|
45
|
+
switch=True,
|
|
46
|
+
),
|
|
47
|
+
html.Div(id="output_cv_folds_ml", style={"color": "red"}),
|
|
48
|
+
],
|
|
49
|
+
className="form_field",
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
_definitionLearningConfig = html.Div(
|
|
53
|
+
className="title_and_form",
|
|
54
|
+
children=[
|
|
55
|
+
html.H4(id="Learn_conf_title", children="Define Learning configs"),
|
|
56
|
+
dbc.Form(
|
|
57
|
+
children=[
|
|
58
|
+
dbc.Col(
|
|
59
|
+
children=[
|
|
60
|
+
__splitConfigFile,
|
|
61
|
+
__ThreadingConfig,
|
|
62
|
+
],
|
|
63
|
+
)
|
|
64
|
+
]
|
|
65
|
+
),
|
|
66
|
+
],
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
__availableAlgorithms = html.Div(
|
|
70
|
+
[
|
|
71
|
+
dbc.Label("Available Algorithms", className="form_labels"),
|
|
72
|
+
dbc.Checklist(
|
|
73
|
+
id="in_algo_ML",
|
|
74
|
+
# inline=True
|
|
75
|
+
),
|
|
76
|
+
html.Div(id="output_checklist_ml", children="", style={"color": "red"}),
|
|
77
|
+
],
|
|
78
|
+
className="form_field",
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
__addCustomAlgorithm = html.Div(
|
|
82
|
+
[
|
|
83
|
+
dbc.Label("Add Sklearn Algorithms", className="form_labels"),
|
|
84
|
+
dbc.Label("from sklearn.A import B"),
|
|
85
|
+
dbc.Input(
|
|
86
|
+
id="import_new_algo",
|
|
87
|
+
placeholder="Complete import (A)",
|
|
88
|
+
className="form_input_text",
|
|
89
|
+
),
|
|
90
|
+
dbc.Input(
|
|
91
|
+
id="name_new_algo",
|
|
92
|
+
placeholder="Enter Name (B)",
|
|
93
|
+
className="form_input_text",
|
|
94
|
+
),
|
|
95
|
+
dbc.Button(
|
|
96
|
+
"Get attributes",
|
|
97
|
+
color="success",
|
|
98
|
+
id="get_attribute_button",
|
|
99
|
+
className="custom_buttons",
|
|
100
|
+
n_clicks=0,
|
|
101
|
+
),
|
|
102
|
+
dbc.Button(
|
|
103
|
+
"Manual configuration",
|
|
104
|
+
color="success",
|
|
105
|
+
id="manual_config_button",
|
|
106
|
+
className="custom_buttons",
|
|
107
|
+
n_clicks=0,
|
|
108
|
+
),
|
|
109
|
+
html.Div(id="output_import_algo"),
|
|
110
|
+
html.Div("WARNING: Incorrect configuration may lead to errors", style={"color": "orange"}),
|
|
111
|
+
html.Br(),
|
|
112
|
+
dbc.Label("Specify parameters to explore by gridsearch"),
|
|
113
|
+
html.Div(id="table_param"),
|
|
114
|
+
html.Div(id="output_error_import_algo"),
|
|
115
|
+
dbc.Label("Specify importance attribute"),
|
|
116
|
+
dbc.Select(
|
|
117
|
+
id="importance_attributes_dropdown_menu",
|
|
118
|
+
),
|
|
119
|
+
dbc.Button(
|
|
120
|
+
"Add",
|
|
121
|
+
color="success",
|
|
122
|
+
id="add_n_refresh_sklearn_algo_button",
|
|
123
|
+
className="custom_buttons",
|
|
124
|
+
n_clicks=0,
|
|
125
|
+
),
|
|
126
|
+
],
|
|
127
|
+
className="form_field",
|
|
128
|
+
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
__validationButton = html.Div(
|
|
132
|
+
id="Learning_button_box",
|
|
133
|
+
className="button_box",
|
|
134
|
+
children=[
|
|
135
|
+
dcc.Loading(
|
|
136
|
+
id="learn_loading",
|
|
137
|
+
children=[
|
|
138
|
+
html.Div(
|
|
139
|
+
id="learn_loading_output",
|
|
140
|
+
style={"color": "green"},
|
|
141
|
+
)
|
|
142
|
+
],
|
|
143
|
+
style={"width": "100%"},
|
|
144
|
+
type="dot",
|
|
145
|
+
color="#13BD00",
|
|
146
|
+
),
|
|
147
|
+
dbc.Button(
|
|
148
|
+
"Learn",
|
|
149
|
+
color="primary",
|
|
150
|
+
id="start_learning_button",
|
|
151
|
+
className="custom_buttons",
|
|
152
|
+
n_clicks=0,
|
|
153
|
+
),
|
|
154
|
+
html.Div(id="output_button_ml", children="", style={"display": "none"}),
|
|
155
|
+
], )
|
|
156
|
+
|
|
157
|
+
_definitionLearningAlgorithm = html.Div(
|
|
158
|
+
className="title_and_form",
|
|
159
|
+
children=[
|
|
160
|
+
html.H4(id="learn_algo_title", children="Define Learning Algorithms"),
|
|
161
|
+
dbc.Form(
|
|
162
|
+
children=[
|
|
163
|
+
dbc.Col(
|
|
164
|
+
children=[
|
|
165
|
+
__availableAlgorithms,
|
|
166
|
+
# TODO: change button style
|
|
167
|
+
dbc.Button(
|
|
168
|
+
"Add custom sklearn algorithm (for experts)",
|
|
169
|
+
id="collapse-button",
|
|
170
|
+
className="mb-3",
|
|
171
|
+
color="outline-primary",
|
|
172
|
+
n_clicks=0,
|
|
173
|
+
),
|
|
174
|
+
dbc.Collapse(
|
|
175
|
+
dbc.Card(dbc.CardBody(__addCustomAlgorithm)),
|
|
176
|
+
id="collapse",
|
|
177
|
+
is_open=False,
|
|
178
|
+
),
|
|
179
|
+
__validationButton,
|
|
180
|
+
],
|
|
181
|
+
)
|
|
182
|
+
]
|
|
183
|
+
),
|
|
184
|
+
],
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
_learn_completed_modal = dbc.Modal(
|
|
188
|
+
[
|
|
189
|
+
dbc.ModalHeader(dbc.ModalTitle("Learning completed")),
|
|
190
|
+
dbc.ModalBody(id="learn_completed_body", children="The learning is completed."),
|
|
191
|
+
dbc.ModalFooter(
|
|
192
|
+
dbc.Button("Close", id="close-learn_completed_modal", className="ml-auto")
|
|
193
|
+
),
|
|
194
|
+
],
|
|
195
|
+
id="learn_completed_modal",
|
|
196
|
+
is_open=False,
|
|
197
|
+
centered=True
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
return dbc.Tab(
|
|
201
|
+
className="global_tab",
|
|
202
|
+
label="Machine Learning",
|
|
203
|
+
children=[
|
|
204
|
+
dcc.Store(id='learn-button-state', data=False),
|
|
205
|
+
dcc.Store(id='classification_design_filename-store', data=""),
|
|
206
|
+
html.Div(
|
|
207
|
+
className="fig_group",
|
|
208
|
+
children=[_definitionLearningConfig, _definitionLearningAlgorithm, _learn_completed_modal],
|
|
209
|
+
),
|
|
210
|
+
],
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
def _registerCallbacks(self) -> None:
|
|
214
|
+
@self.app.callback(
|
|
215
|
+
Output("in_nbr_CV_folds", "value"), [Input("custom_big_tabs", "active_tab")]
|
|
216
|
+
)
|
|
217
|
+
@log_exceptions(self._logger)
|
|
218
|
+
def update_nbr_CV_folds(active_tab):
|
|
219
|
+
if active_tab == "tab-2":
|
|
220
|
+
return self.metabo_controller.get_cv_folds()
|
|
221
|
+
return dash.no_update
|
|
222
|
+
|
|
223
|
+
@self.app.callback(
|
|
224
|
+
Output("switches-input", "options"), [Input("switches-input", "value")]
|
|
225
|
+
)
|
|
226
|
+
def update_switch(value):
|
|
227
|
+
if value == [1]:
|
|
228
|
+
self.metabo_controller.set_multithreading(True)
|
|
229
|
+
return [
|
|
230
|
+
{"label": "Multi-threading is on", "value": 1},
|
|
231
|
+
]
|
|
232
|
+
elif not value:
|
|
233
|
+
self.metabo_controller.set_multithreading(False)
|
|
234
|
+
return [
|
|
235
|
+
{"label": "Multi-threading is off", "value": 1},
|
|
236
|
+
]
|
|
237
|
+
return dash.no_update
|
|
238
|
+
|
|
239
|
+
@self.app.callback(
|
|
240
|
+
[
|
|
241
|
+
Output("in_algo_ML", "options"),
|
|
242
|
+
Output("in_algo_ML", "value"),
|
|
243
|
+
Output("output_checklist_ml", "children"),
|
|
244
|
+
Output("output_error_import_algo", "children"),
|
|
245
|
+
],
|
|
246
|
+
[
|
|
247
|
+
Input("add_n_refresh_sklearn_algo_button", "n_clicks"),
|
|
248
|
+
Input("in_algo_ML", "value"),
|
|
249
|
+
Input("custom_big_tabs", "active_tab"),
|
|
250
|
+
],
|
|
251
|
+
[
|
|
252
|
+
State("import_new_algo", "value"),
|
|
253
|
+
State("name_new_algo", "value"),
|
|
254
|
+
State("table_param", "children"),
|
|
255
|
+
State("importance_attributes_dropdown_menu", "value")
|
|
256
|
+
]
|
|
257
|
+
)
|
|
258
|
+
@log_exceptions(self._logger)
|
|
259
|
+
def add_refresh_available_sklearn_algorithms(
|
|
260
|
+
n, value, active_tab, import_algo, name_algo, table_param, importance_attribute
|
|
261
|
+
):
|
|
262
|
+
triggered_by = callback_context.triggered[0]["prop_id"].split(".")[0]
|
|
263
|
+
if triggered_by == "custom_big_tabs":
|
|
264
|
+
self._logger.info("Triggered by tab")
|
|
265
|
+
if active_tab == "tab-2":
|
|
266
|
+
self.metabo_controller.update_classification_designs_with_selected_models()
|
|
267
|
+
|
|
268
|
+
if triggered_by == "add_n_refresh_sklearn_algo_button":
|
|
269
|
+
grid_search_params = {}
|
|
270
|
+
model = Utils.get_model_from_import([import_algo], name_algo)
|
|
271
|
+
param_types = {param: type for param, type in Utils.get_model_parameters(model)}
|
|
272
|
+
error_children = []
|
|
273
|
+
if "{'props': {'children': 'Name', 'colSpan': 1}, 'type': 'Th', 'namespace': 'dash_html_components'}" in str(
|
|
274
|
+
table_param[-1]["props"]):
|
|
275
|
+
params_and_values = re.findall(r"{'id': '(\w+)'[\w,' :]*'value': '([\[\],. \w]+)',[\w,': ]*}",
|
|
276
|
+
str(table_param))
|
|
277
|
+
try:
|
|
278
|
+
grid_search_params = Utils.transform_params_to_cross_validation_dict(params_and_values,
|
|
279
|
+
param_types)
|
|
280
|
+
except ValueError as e:
|
|
281
|
+
for error in e.args[0]:
|
|
282
|
+
error_children.append(html.P(error, style={"color": "red"}))
|
|
283
|
+
else:
|
|
284
|
+
json_params_and_values = table_param[-1]["props"]["value"]
|
|
285
|
+
try:
|
|
286
|
+
params_and_values = json.loads(json_params_and_values)
|
|
287
|
+
except json.decoder.JSONDecodeError as e:
|
|
288
|
+
return dash.no_update, dash.no_update, dash.no_update, html.P("Error in parameters:" + e.msg,
|
|
289
|
+
style={"color": "red"})
|
|
290
|
+
|
|
291
|
+
if importance_attribute is None:
|
|
292
|
+
error_children.append(html.P("Please select an importance attribute", style={"color": "red"}))
|
|
293
|
+
|
|
294
|
+
if error_children:
|
|
295
|
+
return dash.no_update, dash.no_update, dash.no_update, error_children
|
|
296
|
+
|
|
297
|
+
self.metabo_controller.add_custom_model(
|
|
298
|
+
name_algo, import_algo, grid_search_params, importance_attribute
|
|
299
|
+
)
|
|
300
|
+
if triggered_by == "in_algo_ML":
|
|
301
|
+
self._logger.info("Triggered by dropdown")
|
|
302
|
+
try:
|
|
303
|
+
self.metabo_controller.set_selected_models(value)
|
|
304
|
+
except ValueError as ve:
|
|
305
|
+
self._logger.error(f"{ve}")
|
|
306
|
+
return (
|
|
307
|
+
Utils.format_list_for_checklist(
|
|
308
|
+
self.metabo_controller.get_all_algos_names()
|
|
309
|
+
),
|
|
310
|
+
[],
|
|
311
|
+
str(ve),
|
|
312
|
+
"",
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
return (
|
|
316
|
+
Utils.format_list_for_checklist(
|
|
317
|
+
self.metabo_controller.get_all_algos_names()
|
|
318
|
+
),
|
|
319
|
+
self.metabo_controller.get_selected_models(),
|
|
320
|
+
"",
|
|
321
|
+
"",
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
@self.app.callback(
|
|
325
|
+
[
|
|
326
|
+
Output("output_button_ml", "children"),
|
|
327
|
+
Output("learn_loading_output", "children"),
|
|
328
|
+
Output("learn-button-state", "data"),
|
|
329
|
+
Output('classification_design_filename-store', 'data'),
|
|
330
|
+
],
|
|
331
|
+
[Input("start_learning_button", "n_clicks")],
|
|
332
|
+
)
|
|
333
|
+
@log_exceptions(self._logger)
|
|
334
|
+
def start_machine_learning(n):
|
|
335
|
+
if n >= 1:
|
|
336
|
+
self._logger.info(f"in\n{self.metabo_controller.get_selected_models()}")
|
|
337
|
+
self.metabo_controller.learn()
|
|
338
|
+
|
|
339
|
+
# Dump file to dump folder and to save folder (backup)
|
|
340
|
+
metabo_expe_filename = Utils.get_metabo_experiment_path("pico_ml")
|
|
341
|
+
metabo_expe_obj = self.metabo_controller.generate_save()
|
|
342
|
+
Utils.dump_metabo_expe(metabo_expe_obj) # Dump the classification design to the dump folder
|
|
343
|
+
Utils.dump_metabo_expe(metabo_expe_obj, metabo_expe_filename) # Save classification design.
|
|
344
|
+
del metabo_expe_obj
|
|
345
|
+
self._logger.info(f'The classification design file "{metabo_expe_filename}" has been saved.')
|
|
346
|
+
self._logger.info(f"bip bip 3 : {self.metabo_controller._metabo_experiment.classification_designs}")
|
|
347
|
+
return "Done!", "", True, basename(metabo_expe_filename)
|
|
348
|
+
else:
|
|
349
|
+
return dash.no_update
|
|
350
|
+
|
|
351
|
+
@self.app.callback(
|
|
352
|
+
Output("learn_completed_modal", "is_open"),
|
|
353
|
+
[Input("close-learn_completed_modal", "n_clicks"),
|
|
354
|
+
Input('learn-button-state', 'data')],
|
|
355
|
+
[State("learn_completed_modal", "is_open")]
|
|
356
|
+
)
|
|
357
|
+
def toggle_learn_completed_modal(close_clicks, learn_state, is_open):
|
|
358
|
+
if close_clicks or learn_state:
|
|
359
|
+
return not is_open
|
|
360
|
+
return is_open
|
|
361
|
+
|
|
362
|
+
@self.app.callback(
|
|
363
|
+
Output("learn_completed_body", "children"),
|
|
364
|
+
[Input('classification_design_filename-store', 'data')]
|
|
365
|
+
)
|
|
366
|
+
@log_exceptions(self._logger)
|
|
367
|
+
def update_modal_message(filename):
|
|
368
|
+
if filename:
|
|
369
|
+
return [
|
|
370
|
+
html.P(f'The classification design file "{filename}" has been saved.', style={'color': 'green'}),
|
|
371
|
+
html.P('You can go to the "Results" tabs.'),
|
|
372
|
+
]
|
|
373
|
+
return "Error!"
|
|
374
|
+
|
|
375
|
+
@self.app.callback(
|
|
376
|
+
[Output("radio_cv_types", "value"),
|
|
377
|
+
Output("cv_params", "children")],
|
|
378
|
+
[Input("radio_cv_types", "value"),
|
|
379
|
+
Input("custom_big_tabs", "active_tab"),
|
|
380
|
+
Input({"type": "cv_params", "index": ALL}, "value")],
|
|
381
|
+
)
|
|
382
|
+
@log_exceptions(self._logger)
|
|
383
|
+
def set_cv_type(cv_value, tab, input_params):
|
|
384
|
+
if callback_context.triggered[0]["prop_id"] == "radio_cv_types.value":
|
|
385
|
+
params_form = []
|
|
386
|
+
self.metabo_controller.set_cv_type(cv_value)
|
|
387
|
+
params = self.metabo_controller.get_cv_algorithm_configuration()
|
|
388
|
+
if params:
|
|
389
|
+
for param in params:
|
|
390
|
+
if not param["constant"]:
|
|
391
|
+
name = param["name"]
|
|
392
|
+
value = param["value"]
|
|
393
|
+
type = param["type"]
|
|
394
|
+
if type == "int":
|
|
395
|
+
html_type = "number"
|
|
396
|
+
elif type == "float":
|
|
397
|
+
html_type = "number"
|
|
398
|
+
elif type == "bool":
|
|
399
|
+
html_type = "checkbox"
|
|
400
|
+
else:
|
|
401
|
+
html_type = "text"
|
|
402
|
+
params_form.append(
|
|
403
|
+
html.Tr(
|
|
404
|
+
[
|
|
405
|
+
html.Td(name),
|
|
406
|
+
html.Td(
|
|
407
|
+
dcc.Input(
|
|
408
|
+
id={"type": "cv_params", "index": name},
|
|
409
|
+
type=html_type,
|
|
410
|
+
value=value,
|
|
411
|
+
)
|
|
412
|
+
),
|
|
413
|
+
]
|
|
414
|
+
)
|
|
415
|
+
)
|
|
416
|
+
return cv_value, params_form
|
|
417
|
+
else:
|
|
418
|
+
if input_params is not None and input_params != []:
|
|
419
|
+
self.metabo_controller.set_cv_algorithm_configuration(input_params)
|
|
420
|
+
|
|
421
|
+
return self.metabo_controller.get_selected_cv_type(), dash.no_update
|
|
422
|
+
|
|
423
|
+
@self.app.callback(
|
|
424
|
+
[Output("output_import_algo", "children"),
|
|
425
|
+
Output("output_import_algo", "style"),
|
|
426
|
+
Output("table_param", "children"),
|
|
427
|
+
Output("importance_attributes_dropdown_menu", "options")],
|
|
428
|
+
[Input("get_attribute_button", "n_clicks"),
|
|
429
|
+
Input("manual_config_button", "n_clicks")],
|
|
430
|
+
[State("import_new_algo", "value"),
|
|
431
|
+
State("name_new_algo", "value")],
|
|
432
|
+
)
|
|
433
|
+
@log_exceptions(self._logger)
|
|
434
|
+
def get_attribute_algo(n_attribute, n_manual, import_new, new_algo_name):
|
|
435
|
+
triggered_by = callback_context.triggered[0]["prop_id"].split(".")[0]
|
|
436
|
+
self._logger.info(f"triggered by: [{triggered_by}]")
|
|
437
|
+
if n_manual > 0 or n_attribute > 0:
|
|
438
|
+
try:
|
|
439
|
+
model = Utils.get_model_from_import([import_new], new_algo_name)
|
|
440
|
+
except Exception as e:
|
|
441
|
+
self._logger.error(f"{e}")
|
|
442
|
+
return "Import failed: " + str(e), {"color": "red"}, "", ""
|
|
443
|
+
importance_attributes = [param_name for param_name, _ in
|
|
444
|
+
Utils.get_model_parameters_after_training(model)]
|
|
445
|
+
if not importance_attributes:
|
|
446
|
+
return "Import failed: No importance attribute found.", {"color": "red"}, "", ""
|
|
447
|
+
if triggered_by == "get_attribute_button":
|
|
448
|
+
try:
|
|
449
|
+
attributes = Utils.get_model_parameters(model)
|
|
450
|
+
attributes_table = pd.DataFrame(attributes, columns=["Name", "Type"])
|
|
451
|
+
attributes_table["Type"].replace(
|
|
452
|
+
{"str": "String", "int": "Integer", "float": "Float", "NoneType": "Unspecified"},
|
|
453
|
+
inplace=True)
|
|
454
|
+
inputs = []
|
|
455
|
+
for attribute, _ in attributes:
|
|
456
|
+
inputs.append(dbc.Input(id=attribute, type="text", placeholder="Value"))
|
|
457
|
+
attributes_table["Value"] = inputs
|
|
458
|
+
|
|
459
|
+
default_text = [
|
|
460
|
+
html.Br(),
|
|
461
|
+
html.P("You can set the grid search parameters as followed:"),
|
|
462
|
+
html.P(
|
|
463
|
+
"Values: 'val1A, val1B, val1C'"
|
|
464
|
+
),
|
|
465
|
+
dbc.Table.from_dataframe(attributes_table)
|
|
466
|
+
]
|
|
467
|
+
|
|
468
|
+
return f"{model.__name__} found", {
|
|
469
|
+
"color": "green"}, default_text, Utils.format_list_for_checklist(importance_attributes)
|
|
470
|
+
except Exception as e:
|
|
471
|
+
self._logger.info(f"{e}")
|
|
472
|
+
return "Import failed: " + str(e), {"color": "red"}, "", ""
|
|
473
|
+
elif triggered_by == "manual_config_button":
|
|
474
|
+
return "", None, [html.P("The following configuration must be in JSON format",
|
|
475
|
+
style={"color": "orange"}), html.Br(),
|
|
476
|
+
dcc.Textarea()], Utils.format_list_for_checklist(importance_attributes)
|
|
477
|
+
return dash.no_update, dash.no_update, dash.no_update, dash.no_update
|
|
478
|
+
|
|
479
|
+
@self.app.callback(
|
|
480
|
+
Output("collapse", "is_open"),
|
|
481
|
+
[Input("collapse-button", "n_clicks")],
|
|
482
|
+
[State("collapse", "is_open")],
|
|
483
|
+
)
|
|
484
|
+
def toggle_collapse(n, is_open):
|
|
485
|
+
if n:
|
|
486
|
+
return not is_open
|
|
487
|
+
return is_open
|
pico/ui/tabs/MetaTab.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from abc import abstractmethod
|
|
2
|
+
import dash_bootstrap_components as dbc
|
|
3
|
+
|
|
4
|
+
from dash import Dash
|
|
5
|
+
|
|
6
|
+
from ...domain import Controller
|
|
7
|
+
from ...service import init_logger
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MetaTab:
|
|
11
|
+
def __init__(self, app: Dash, metabo_controller: Controller):
|
|
12
|
+
self._logger = init_logger()
|
|
13
|
+
self.metabo_controller = metabo_controller
|
|
14
|
+
self.app = app
|
|
15
|
+
self._registerCallbacks()
|
|
16
|
+
|
|
17
|
+
@abstractmethod
|
|
18
|
+
def getLayout(self) -> dbc.Tab:
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
@abstractmethod
|
|
22
|
+
def _registerCallbacks(self) -> None:
|
|
23
|
+
pass
|