pyfemtet 0.4.12__py3-none-any.whl → 0.4.14__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 pyfemtet might be problematic. Click here for more details.
- pyfemtet/__init__.py +1 -1
- pyfemtet/dispatch_extensions.py +4 -0
- pyfemtet/message/1. make_pot.bat +12 -0
- pyfemtet/message/2. make_mo.bat +6 -0
- pyfemtet/message/__init__.py +5 -0
- pyfemtet/message/babel.cfg +2 -0
- pyfemtet/message/locales/ja/LC_MESSAGES/messages.po +449 -0
- pyfemtet/message/locales/messages.pot +439 -0
- pyfemtet/message/messages.py +174 -0
- pyfemtet/opt/_femopt.py +9 -9
- pyfemtet/opt/_femopt_core.py +22 -17
- pyfemtet/opt/femprj_sample/ParametricIF - True.femprj +0 -0
- pyfemtet/opt/femprj_sample/ParametricIF.femprj +0 -0
- pyfemtet/opt/femprj_sample/ParametricIF.py +31 -0
- pyfemtet/opt/femprj_sample/ParametricIF_test_result.reccsv +13 -0
- pyfemtet/opt/femprj_sample/cad_ex01_NX_test_result.reccsv +13 -13
- pyfemtet/opt/femprj_sample/cad_ex01_SW_test_result.reccsv +13 -13
- pyfemtet/opt/femprj_sample/gal_ex58_parametric_test_result.reccsv +13 -13
- pyfemtet/opt/femprj_sample/gau_ex08_parametric_test_result.reccsv +23 -23
- pyfemtet/opt/femprj_sample/her_ex40_parametric_test_result.reccsv +18 -18
- pyfemtet/opt/femprj_sample/paswat_ex1_parametric_test_result.reccsv +18 -18
- pyfemtet/opt/femprj_sample/tutorial.femprj +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial1.jpg +0 -0
- pyfemtet/opt/{visualization/result_viewer/tutorial → femprj_sample}/wat_ex14_parametric.Results/Ex14_trial1.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial10.jpg +0 -0
- pyfemtet/opt/{visualization/result_viewer/tutorial → femprj_sample}/wat_ex14_parametric.Results/Ex14_trial10.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial11.jpg +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial11.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial12.jpg +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial12.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial13.jpg +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial13.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial14.jpg +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial14.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial15.jpg +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial15.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial2.jpg +0 -0
- pyfemtet/opt/{visualization/result_viewer/tutorial → femprj_sample}/wat_ex14_parametric.Results/Ex14_trial2.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial3.jpg +0 -0
- pyfemtet/opt/{visualization/result_viewer/tutorial → femprj_sample}/wat_ex14_parametric.Results/Ex14_trial3.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial4.jpg +0 -0
- pyfemtet/opt/{visualization/result_viewer/tutorial → femprj_sample}/wat_ex14_parametric.Results/Ex14_trial4.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial5.jpg +0 -0
- pyfemtet/opt/{visualization/result_viewer/tutorial → femprj_sample}/wat_ex14_parametric.Results/Ex14_trial5.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial6.jpg +0 -0
- pyfemtet/opt/{visualization/result_viewer/tutorial → femprj_sample}/wat_ex14_parametric.Results/Ex14_trial6.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial7.jpg +0 -0
- pyfemtet/opt/{visualization/result_viewer/tutorial → femprj_sample}/wat_ex14_parametric.Results/Ex14_trial7.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial8.jpg +0 -0
- pyfemtet/opt/{visualization/result_viewer/tutorial → femprj_sample}/wat_ex14_parametric.Results/Ex14_trial8.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial9.jpg +0 -0
- pyfemtet/opt/{visualization/result_viewer/tutorial → femprj_sample}/wat_ex14_parametric.Results/Ex14_trial9.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric_test_result.reccsv +18 -18
- pyfemtet/opt/femprj_sample_jp/ParametricIF_jp.femprj +0 -0
- pyfemtet/opt/femprj_sample_jp/ParametricIF_jp.py +31 -0
- pyfemtet/opt/interface/_femtet.py +45 -47
- pyfemtet/opt/interface/_femtet_parametric.py +7 -2
- pyfemtet/opt/interface/_femtet_with_nx/_interface.py +4 -4
- pyfemtet/opt/interface/_femtet_with_nx/update_model.py +6 -6
- pyfemtet/opt/interface/_femtet_with_sldworks.py +5 -4
- pyfemtet/opt/opt/__init__.py +2 -0
- pyfemtet/opt/opt/_base.py +41 -20
- pyfemtet/opt/opt/_optuna.py +8 -13
- pyfemtet/opt/opt/_scipy.py +4 -8
- pyfemtet/opt/opt/_scipy_scalar.py +1 -5
- pyfemtet/opt/prediction/__init__.py +0 -0
- pyfemtet/opt/prediction/base.py +52 -0
- pyfemtet/opt/prediction/single_task_gp.py +82 -0
- pyfemtet/opt/visualization/complex_components/control_femtet.py +9 -11
- pyfemtet/opt/visualization/complex_components/main_figure_creator.py +24 -11
- pyfemtet/opt/visualization/complex_components/main_graph.py +3 -4
- pyfemtet/opt/visualization/complex_components/pm_graph.py +715 -0
- pyfemtet/opt/visualization/complex_components/pm_graph_creator.py +168 -0
- pyfemtet/opt/visualization/process_monitor/application.py +16 -12
- pyfemtet/opt/visualization/process_monitor/pages.py +22 -7
- pyfemtet/opt/visualization/result_viewer/application.py +8 -3
- pyfemtet/opt/visualization/result_viewer/pages.py +59 -47
- {pyfemtet-0.4.12.dist-info → pyfemtet-0.4.14.dist-info}/METADATA +2 -1
- pyfemtet-0.4.14.dist-info/RECORD +151 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/tutorial.csv +0 -18
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14.log +0 -81
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14.pdt +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_heatflow.csv +0 -28
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_heatflow_el.csv +0 -22
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial1.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial10.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial11.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial11.pdt +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial12.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial12.pdt +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial13.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial13.pdt +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial14.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial14.pdt +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial15.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial15.pdt +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial2.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial3.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial4.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial5.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial6.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial7.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial8.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial9.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.femprj +0 -0
- pyfemtet-0.4.12.dist-info/RECORD +0 -138
- {pyfemtet-0.4.12.dist-info → pyfemtet-0.4.14.dist-info}/LICENSE +0 -0
- {pyfemtet-0.4.12.dist-info → pyfemtet-0.4.14.dist-info}/WHEEL +0 -0
- {pyfemtet-0.4.12.dist-info → pyfemtet-0.4.14.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
from typing import Callable, List
|
|
2
|
+
|
|
3
|
+
import torch
|
|
4
|
+
import numpy as np
|
|
5
|
+
import pandas as pd
|
|
6
|
+
|
|
7
|
+
import plotly.graph_objs as go
|
|
8
|
+
import plotly.express as px
|
|
9
|
+
|
|
10
|
+
from pyfemtet.opt._femopt_core import History
|
|
11
|
+
|
|
12
|
+
from pyfemtet.opt.prediction.base import PyFemtetPredictionModel
|
|
13
|
+
from pyfemtet.opt.prediction.single_task_gp import SingleTaskGPModel
|
|
14
|
+
from pyfemtet.message import Msg
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class PredictionModelCreator:
|
|
18
|
+
|
|
19
|
+
# noinspection PyAttributeOutsideInit
|
|
20
|
+
def fit(self, history, df):
|
|
21
|
+
# common
|
|
22
|
+
self.history = history # used to check fit or not
|
|
23
|
+
self.df = df
|
|
24
|
+
# method specific
|
|
25
|
+
self.pmm = PyFemtetPredictionModel(history, df, SingleTaskGPModel)
|
|
26
|
+
self.pmm.fit()
|
|
27
|
+
|
|
28
|
+
def create_figure(
|
|
29
|
+
self,
|
|
30
|
+
prm_name_1: str,
|
|
31
|
+
obj_name: str,
|
|
32
|
+
remaining_x: list[float],
|
|
33
|
+
prm_name_2: str = '',
|
|
34
|
+
):
|
|
35
|
+
|
|
36
|
+
history = self.history
|
|
37
|
+
df = self.df
|
|
38
|
+
|
|
39
|
+
# determine axis1, axis2 range
|
|
40
|
+
lb1 = df[f'{prm_name_1}_lower_bound'].min()
|
|
41
|
+
ub1 = df[f'{prm_name_1}_upper_bound'].max()
|
|
42
|
+
lb1 = df[prm_name_1].min() if np.isnan(lb1) else lb1
|
|
43
|
+
ub1 = df[prm_name_1].max() if np.isnan(ub1) else ub1
|
|
44
|
+
if prm_name_2:
|
|
45
|
+
lb2 = df[f'{prm_name_2}_lower_bound'].min()
|
|
46
|
+
ub2 = df[f'{prm_name_2}_upper_bound'].max()
|
|
47
|
+
lb2 = df[prm_name_2].min() if np.isnan(lb2) else lb2
|
|
48
|
+
ub2 = df[prm_name_2].max() if np.isnan(ub2) else ub2
|
|
49
|
+
|
|
50
|
+
# create grid data
|
|
51
|
+
if prm_name_2:
|
|
52
|
+
N = 20
|
|
53
|
+
x_grid = np.linspace(lb1, ub1, N) # shape: (N,)
|
|
54
|
+
y_grid = np.linspace(lb2, ub2, N)
|
|
55
|
+
xx, yy = np.meshgrid(x_grid, y_grid) # shape: (N, N)
|
|
56
|
+
else:
|
|
57
|
+
N = 100
|
|
58
|
+
xx = np.linspace(lb1, ub1, N) # shape: (N,)
|
|
59
|
+
|
|
60
|
+
# create raveled grid data
|
|
61
|
+
tmp_df = pd.DataFrame(columns=history.prm_names)
|
|
62
|
+
idx = 0
|
|
63
|
+
for prm_name in history.prm_names:
|
|
64
|
+
if prm_name == prm_name_1:
|
|
65
|
+
tmp_df[prm_name_1] = xx.ravel() # shape: (N**2,) or (N,)
|
|
66
|
+
elif prm_name == prm_name_2: # no chance to hit if prm_name_2 == ''
|
|
67
|
+
tmp_df[prm_name_2] = yy.ravel()
|
|
68
|
+
else:
|
|
69
|
+
tmp_df[prm_name] = remaining_x[idx]
|
|
70
|
+
idx += 1
|
|
71
|
+
x = tmp_df.values # shape: (len(prm), N**2)
|
|
72
|
+
|
|
73
|
+
# predict by model
|
|
74
|
+
mean, std = self.pmm.predict(x) # shape: (len(obj), N**2)
|
|
75
|
+
|
|
76
|
+
# create mesh data for graph
|
|
77
|
+
obj_index = history.obj_names.index(obj_name)
|
|
78
|
+
zz_mean = mean[:, obj_index].reshape(xx.shape) # shape: (N**2,) -> (N, N) or (N,) -> (N,)
|
|
79
|
+
zz_std = std[:, obj_index].reshape(xx.shape)
|
|
80
|
+
zz_upper = zz_mean + zz_std
|
|
81
|
+
zz_lower = zz_mean - zz_std
|
|
82
|
+
|
|
83
|
+
# ===== create figure =====
|
|
84
|
+
# description: データ点は多次元空間上の点なので、余剰次元を無視して三次元空間上に投影しても何の意味もない。むしろ混乱するのでやってはいけない。実験的機能として、透明度を設定してみる。
|
|
85
|
+
# calculate distance from super-plane to prm point for opacity of scatter plot
|
|
86
|
+
remaining_prm = list(history.prm_names) # weak copy
|
|
87
|
+
remaining_prm.remove(prm_name_1)
|
|
88
|
+
remaining_prm.remove(prm_name_2) if prm_name_2 in remaining_prm else None
|
|
89
|
+
if len(remaining_prm) > 0:
|
|
90
|
+
super_plane = np.array(remaining_x) # shape: (len(prm_names)-2) or (len(prm_names)-1)
|
|
91
|
+
target_point = df[remaining_prm].values # shape: (len(df), len(prm_names)-2) or (len(df), len(prm_names)-1)
|
|
92
|
+
distance = np.linalg.norm(target_point-super_plane, axis=1, keepdims=False) # shape: (len(df))
|
|
93
|
+
opacity = 1 - (distance / distance.max()) # smaller distance, larger opacity
|
|
94
|
+
else:
|
|
95
|
+
opacity = np.ones(len(df))
|
|
96
|
+
|
|
97
|
+
# scatter plot
|
|
98
|
+
if prm_name_2:
|
|
99
|
+
fig = go.Figure(data=go.Scatter3d(
|
|
100
|
+
x=df[prm_name_1], y=df[prm_name_2], z=df[obj_name],
|
|
101
|
+
mode='markers',
|
|
102
|
+
marker=dict(
|
|
103
|
+
size=3,
|
|
104
|
+
color='black',
|
|
105
|
+
),
|
|
106
|
+
name='trial',
|
|
107
|
+
))
|
|
108
|
+
else:
|
|
109
|
+
fig = go.Figure(data=go.Scatter(
|
|
110
|
+
x=df[prm_name_1], y=df[obj_name],
|
|
111
|
+
mode='markers',
|
|
112
|
+
marker=dict(
|
|
113
|
+
color='black',
|
|
114
|
+
),
|
|
115
|
+
name='trial',
|
|
116
|
+
))
|
|
117
|
+
|
|
118
|
+
# set opacity by its distance
|
|
119
|
+
def set_opacity(trace):
|
|
120
|
+
trace.marker.color = [f'rgba(0, 0, 0, {o})' for o in opacity]
|
|
121
|
+
fig.for_each_trace(set_opacity)
|
|
122
|
+
|
|
123
|
+
# main RSM
|
|
124
|
+
if prm_name_2:
|
|
125
|
+
contours = dict(
|
|
126
|
+
x=dict(
|
|
127
|
+
highlight=False, show=True, color='blue',
|
|
128
|
+
start=lb1, end=ub1, size=(ub1-lb1)/N,
|
|
129
|
+
),
|
|
130
|
+
y=dict(
|
|
131
|
+
highlight=False, show=True, color='blue',
|
|
132
|
+
start=lb2, end=ub2, size=(ub1-lb1)/N
|
|
133
|
+
),
|
|
134
|
+
z=dict(highlight=False, show=False),
|
|
135
|
+
)
|
|
136
|
+
fig.add_trace(go.Surface(z=zz_mean, x=xx, y=yy, contours=contours))
|
|
137
|
+
# std
|
|
138
|
+
fig.add_trace(go.Surface(z=zz_upper, x=xx, y=yy, showscale=False, opacity=0.3))
|
|
139
|
+
fig.add_trace(go.Surface(z=zz_lower, x=xx, y=yy, showscale=False, opacity=0.3))
|
|
140
|
+
|
|
141
|
+
# layout
|
|
142
|
+
fig.update_layout(
|
|
143
|
+
title=Msg.GRAPH_TITLE_PREDICTION_MODEL,
|
|
144
|
+
scene=dict(
|
|
145
|
+
xaxis_title=prm_name_1,
|
|
146
|
+
yaxis_title=prm_name_2,
|
|
147
|
+
zaxis_title=obj_name
|
|
148
|
+
),
|
|
149
|
+
margin=dict(l=0, r=0, b=0, t=0),
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
else:
|
|
154
|
+
fig.add_trace(
|
|
155
|
+
go.Scatter(x=xx, y=zz_mean, name=Msg.LEGEND_LABEL_PREDICTION_MODEL)
|
|
156
|
+
)
|
|
157
|
+
# std
|
|
158
|
+
fig.add_trace(
|
|
159
|
+
go.Scatter(
|
|
160
|
+
x=np.concatenate([xx, xx[::-1]]),
|
|
161
|
+
y=np.concatenate([zz_upper, zz_lower[::-1]]),
|
|
162
|
+
opacity=0.3,
|
|
163
|
+
fill='toself',
|
|
164
|
+
name=Msg.LEGEND_LABEL_PREDICTION_MODEL_STDDEV,
|
|
165
|
+
)
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
return fig
|
|
@@ -5,7 +5,8 @@ from threading import Thread
|
|
|
5
5
|
import pandas as pd
|
|
6
6
|
|
|
7
7
|
from pyfemtet.opt.visualization.base import PyFemtetApplicationBase, logger
|
|
8
|
-
from pyfemtet.opt.visualization.process_monitor.pages import HomePage, WorkerPage
|
|
8
|
+
from pyfemtet.opt.visualization.process_monitor.pages import HomePage, WorkerPage, PredictionModelPage
|
|
9
|
+
from pyfemtet.message import Msg
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class ProcessMonitorApplication(PyFemtetApplicationBase):
|
|
@@ -68,7 +69,6 @@ class ProcessMonitorApplication(PyFemtetApplicationBase):
|
|
|
68
69
|
else:
|
|
69
70
|
return self.history.local_data
|
|
70
71
|
|
|
71
|
-
|
|
72
72
|
@local_data.setter
|
|
73
73
|
def local_data(self, value: pd.DataFrame):
|
|
74
74
|
if self._should_get_actor_data:
|
|
@@ -76,7 +76,6 @@ class ProcessMonitorApplication(PyFemtetApplicationBase):
|
|
|
76
76
|
else:
|
|
77
77
|
self.history.local_data = value
|
|
78
78
|
|
|
79
|
-
|
|
80
79
|
def setup_callback(self, debug=False):
|
|
81
80
|
if not debug:
|
|
82
81
|
super().setup_callback()
|
|
@@ -124,7 +123,8 @@ class ProcessMonitorApplication(PyFemtetApplicationBase):
|
|
|
124
123
|
# interval
|
|
125
124
|
sleep(1)
|
|
126
125
|
|
|
127
|
-
|
|
126
|
+
@staticmethod
|
|
127
|
+
def get_status_color(status_int):
|
|
128
128
|
from pyfemtet.opt._femopt_core import OptimizationStatus
|
|
129
129
|
# set color
|
|
130
130
|
if status_int <= OptimizationStatus.SETTING_UP:
|
|
@@ -171,27 +171,31 @@ def g_debug():
|
|
|
171
171
|
status=_OS('entire'),
|
|
172
172
|
worker_addresses=['worker1', 'worker2', 'worker3'],
|
|
173
173
|
worker_status_list=[_OS('worker1'), _OS('worker2'), _OS('worker3')],
|
|
174
|
-
is_debug=
|
|
174
|
+
is_debug=False,
|
|
175
175
|
)
|
|
176
176
|
|
|
177
|
-
g_home_page = HomePage(
|
|
178
|
-
|
|
177
|
+
g_home_page = HomePage(Msg.PAGE_TITLE_PROGRESS)
|
|
178
|
+
g_rsm_page = PredictionModelPage(Msg.PAGE_TITLE_PREDICTION_MODEL, '/prediction-model', g_application)
|
|
179
|
+
g_worker_page = WorkerPage(Msg.PAGE_TITLE_WORKERS, '/workers', g_application)
|
|
179
180
|
|
|
180
181
|
g_application.add_page(g_home_page, 0)
|
|
181
|
-
g_application.add_page(
|
|
182
|
+
g_application.add_page(g_rsm_page, 1)
|
|
183
|
+
g_application.add_page(g_worker_page, 2)
|
|
182
184
|
g_application.setup_callback(debug=False)
|
|
183
185
|
|
|
184
|
-
g_application.run(debug=
|
|
186
|
+
g_application.run(debug=False)
|
|
185
187
|
|
|
186
188
|
|
|
187
189
|
def main(history, status, worker_addresses, worker_status_list, host=None, port=None):
|
|
188
190
|
g_application = ProcessMonitorApplication(history, status, worker_addresses, worker_status_list)
|
|
189
191
|
|
|
190
|
-
g_home_page = HomePage(
|
|
191
|
-
|
|
192
|
+
g_home_page = HomePage(Msg.PAGE_TITLE_PROGRESS)
|
|
193
|
+
g_rsm_page = PredictionModelPage(Msg.PAGE_TITLE_PREDICTION_MODEL, '/prediction-model', g_application)
|
|
194
|
+
g_worker_page = WorkerPage(Msg.PAGE_TITLE_WORKERS, '/workers', g_application)
|
|
192
195
|
|
|
193
196
|
g_application.add_page(g_home_page, 0)
|
|
194
|
-
g_application.add_page(
|
|
197
|
+
g_application.add_page(g_rsm_page, 1)
|
|
198
|
+
g_application.add_page(g_worker_page, 2)
|
|
195
199
|
g_application.setup_callback()
|
|
196
200
|
|
|
197
201
|
g_application.start_server(host, port)
|
|
@@ -7,6 +7,8 @@ from dash.exceptions import PreventUpdate
|
|
|
7
7
|
from pyfemtet.opt.visualization.wrapped_components import dcc, dbc, html
|
|
8
8
|
from pyfemtet.opt.visualization.base import AbstractPage, logger
|
|
9
9
|
from pyfemtet.opt.visualization.complex_components.main_graph import MainGraph # , FLEXBOX_STYLE_ALLOW_VERTICAL_FILL
|
|
10
|
+
from pyfemtet.opt.visualization.complex_components.pm_graph import PredictionModelGraph
|
|
11
|
+
from pyfemtet.message import Msg
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
DBC_COLUMN_STYLE_CENTER = {
|
|
@@ -40,7 +42,7 @@ class HomePage(AbstractPage):
|
|
|
40
42
|
# entire optimization status
|
|
41
43
|
# noinspection PyAttributeOutsideInit
|
|
42
44
|
self.entire_status_message = html.H4(
|
|
43
|
-
|
|
45
|
+
Msg.DEFAULT_STATUS_ALERT,
|
|
44
46
|
className='alert-heading',
|
|
45
47
|
id='optimization-entire-status-message',
|
|
46
48
|
)
|
|
@@ -54,7 +56,7 @@ class HomePage(AbstractPage):
|
|
|
54
56
|
# stop update button
|
|
55
57
|
# noinspection PyAttributeOutsideInit
|
|
56
58
|
self.toggle_update_graph_button = dbc.Checkbox(
|
|
57
|
-
label=
|
|
59
|
+
label=Msg.LABEL_AUTO_UPDATE,
|
|
58
60
|
class_name='form-switch',
|
|
59
61
|
id='toggle-update-graph',
|
|
60
62
|
value=True,
|
|
@@ -63,7 +65,7 @@ class HomePage(AbstractPage):
|
|
|
63
65
|
# interrupt button
|
|
64
66
|
# noinspection PyAttributeOutsideInit
|
|
65
67
|
self.interrupt_button = dbc.Button(
|
|
66
|
-
children=
|
|
68
|
+
children=Msg.LABEL_INTERRUPT,
|
|
67
69
|
color='danger',
|
|
68
70
|
id='interrupt-optimization-button',
|
|
69
71
|
disabled=True,
|
|
@@ -71,7 +73,7 @@ class HomePage(AbstractPage):
|
|
|
71
73
|
|
|
72
74
|
# sync interval
|
|
73
75
|
# noinspection PyAttributeOutsideInit
|
|
74
|
-
self.interval = dcc.Interval(id='process-monitor-home-interval', interval=
|
|
76
|
+
self.interval = dcc.Interval(id='process-monitor-home-interval', interval=3000)
|
|
75
77
|
|
|
76
78
|
def setup_layout(self):
|
|
77
79
|
""""""
|
|
@@ -131,9 +133,6 @@ class HomePage(AbstractPage):
|
|
|
131
133
|
State(self.main_graph.data_length.id, self.main_graph.data_length_prop), # check should update or not
|
|
132
134
|
prevent_initial_call=True,)
|
|
133
135
|
def update_graph(_, update_switch, current_graph_data_length):
|
|
134
|
-
logger.debug('====================')
|
|
135
|
-
logger.debug(f'update_graph called by {callback_context.triggered_id}')
|
|
136
|
-
|
|
137
136
|
current_graph_data_length = 0 if current_graph_data_length is None else current_graph_data_length
|
|
138
137
|
|
|
139
138
|
if callback_context.triggered_id is None:
|
|
@@ -274,3 +273,19 @@ class WorkerPage(AbstractPage):
|
|
|
274
273
|
ret.append([({} if callback_context.triggered_id is None else no_update) for _ in range(len(self.worker_status_alerts))])
|
|
275
274
|
|
|
276
275
|
return tuple(ret)
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
class PredictionModelPage(AbstractPage):
|
|
279
|
+
""""""
|
|
280
|
+
|
|
281
|
+
def __init__(self, title, rel_url, application):
|
|
282
|
+
from pyfemtet.opt.visualization.process_monitor.application import ProcessMonitorApplication
|
|
283
|
+
self.application: ProcessMonitorApplication = None
|
|
284
|
+
super().__init__(title, rel_url, application)
|
|
285
|
+
|
|
286
|
+
def setup_component(self):
|
|
287
|
+
self.rsm_graph: PredictionModelGraph = PredictionModelGraph()
|
|
288
|
+
self.add_subpage(self.rsm_graph)
|
|
289
|
+
|
|
290
|
+
def setup_layout(self):
|
|
291
|
+
self.layout = self.rsm_graph.layout
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from pyfemtet.opt.visualization.base import PyFemtetApplicationBase
|
|
2
|
-
from pyfemtet.opt.visualization.result_viewer.pages import HomePage
|
|
2
|
+
from pyfemtet.opt.visualization.result_viewer.pages import HomePage, PredictionModelPage
|
|
3
|
+
from pyfemtet.message import Msg
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
class ResultViewerApplication(PyFemtetApplicationBase):
|
|
@@ -21,9 +22,11 @@ def debug():
|
|
|
21
22
|
|
|
22
23
|
g_application = ResultViewerApplication()
|
|
23
24
|
|
|
24
|
-
g_home_page = HomePage(
|
|
25
|
+
g_home_page = HomePage(Msg.PAGE_TITLE_RESULT)
|
|
26
|
+
g_rsm_page = PredictionModelPage(Msg.PAGE_TITLE_PREDICTION_MODEL, '/prediction-model', g_application)
|
|
25
27
|
|
|
26
28
|
g_application.add_page(g_home_page, 0)
|
|
29
|
+
g_application.add_page(g_rsm_page, 1)
|
|
27
30
|
g_application.setup_callback()
|
|
28
31
|
|
|
29
32
|
g_application.run(debug=True)
|
|
@@ -32,9 +35,11 @@ def debug():
|
|
|
32
35
|
def main():
|
|
33
36
|
g_application = ResultViewerApplication()
|
|
34
37
|
|
|
35
|
-
g_home_page = HomePage(
|
|
38
|
+
g_home_page = HomePage(Msg.PAGE_TITLE_RESULT)
|
|
39
|
+
g_rsm_page = PredictionModelPage(Msg.PAGE_TITLE_PREDICTION_MODEL, '/prediction-model', g_application)
|
|
36
40
|
|
|
37
41
|
g_application.add_page(g_home_page, 0)
|
|
42
|
+
g_application.add_page(g_rsm_page, 1)
|
|
38
43
|
g_application.setup_callback()
|
|
39
44
|
|
|
40
45
|
g_application.run()
|
|
@@ -15,9 +15,12 @@ from pyfemtet.opt.visualization.base import AbstractPage # , logger
|
|
|
15
15
|
from pyfemtet.opt.visualization.complex_components.main_graph import MainGraph # , FLEXBOX_STYLE_ALLOW_VERTICAL_FILL
|
|
16
16
|
from pyfemtet.opt.visualization.complex_components.control_femtet import FemtetControl, FemtetState
|
|
17
17
|
from pyfemtet.opt.visualization.complex_components.alert_region import AlertRegion
|
|
18
|
+
from pyfemtet.opt.visualization.complex_components.pm_graph import PredictionModelGraph
|
|
18
19
|
|
|
19
20
|
from pyfemtet.opt._femopt_core import History
|
|
20
21
|
|
|
22
|
+
from pyfemtet.message import Msg
|
|
23
|
+
|
|
21
24
|
|
|
22
25
|
class HomePage(AbstractPage):
|
|
23
26
|
|
|
@@ -43,7 +46,7 @@ class HomePage(AbstractPage):
|
|
|
43
46
|
|
|
44
47
|
# open pdt (or transfer variable to femtet)
|
|
45
48
|
self.open_pdt_button = dbc.Button(
|
|
46
|
-
|
|
49
|
+
Msg.LABEL_OPEN_PDT_BUTTON,
|
|
47
50
|
id='open-pdt-button',
|
|
48
51
|
color='primary',
|
|
49
52
|
className="position-relative", # need to show badge
|
|
@@ -51,14 +54,14 @@ class HomePage(AbstractPage):
|
|
|
51
54
|
|
|
52
55
|
# update parameter
|
|
53
56
|
self.update_parameter_button = dbc.Button(
|
|
54
|
-
|
|
57
|
+
Msg.LABEL_RECONSTRUCT_MODEL_BUTTON,
|
|
55
58
|
id='update-parameter-button',
|
|
56
59
|
color='secondary',
|
|
57
60
|
)
|
|
58
61
|
|
|
59
62
|
# file picker
|
|
60
63
|
self.file_picker_button = dbc.Button(
|
|
61
|
-
|
|
64
|
+
Msg.LABEL_FILE_PICKER,
|
|
62
65
|
id='file-picker-button',
|
|
63
66
|
color='primary',
|
|
64
67
|
)
|
|
@@ -169,14 +172,13 @@ class HomePage(AbstractPage):
|
|
|
169
172
|
# check Femtet state
|
|
170
173
|
connection_state = self.femtet_control.check_femtet_state()
|
|
171
174
|
if connection_state == FemtetState.missing or connection_state == FemtetState.unconnected:
|
|
172
|
-
msg =
|
|
173
|
-
'Launch Femtet and Open a project.')
|
|
175
|
+
msg = Msg.ERR_NO_CONNECTION_ESTABLISHED
|
|
174
176
|
alerts = self.alert_region.create_alerts(msg, color='danger', current_alerts=current_alerts)
|
|
175
177
|
return alerts
|
|
176
178
|
|
|
177
179
|
# check selection
|
|
178
180
|
if selection_data is None:
|
|
179
|
-
msg =
|
|
181
|
+
msg = Msg.ERR_NO_SOLUTION_SELECTED
|
|
180
182
|
alerts = self.alert_region.create_alerts(msg, color='danger', current_alerts=current_alerts)
|
|
181
183
|
return alerts
|
|
182
184
|
|
|
@@ -187,12 +189,12 @@ class HomePage(AbstractPage):
|
|
|
187
189
|
|
|
188
190
|
# check metadata is valid
|
|
189
191
|
if femprj_path is None:
|
|
190
|
-
msg =
|
|
192
|
+
msg = Msg.ERR_FEMPRJ_IN_CSV_NOT_FOUND
|
|
191
193
|
alerts = self.alert_region.create_alerts(msg, color='danger')
|
|
192
194
|
return alerts
|
|
193
195
|
|
|
194
196
|
if model_name is None:
|
|
195
|
-
msg =
|
|
197
|
+
msg = Msg.ERR_MODEL_IN_CSV_NOT_FOUND
|
|
196
198
|
alerts = self.alert_region.create_alerts(msg, color='danger')
|
|
197
199
|
return alerts
|
|
198
200
|
|
|
@@ -218,7 +220,7 @@ class HomePage(AbstractPage):
|
|
|
218
220
|
succeed = Femtet.OpenPDT(pdt_path, True)
|
|
219
221
|
|
|
220
222
|
if not succeed:
|
|
221
|
-
msg =
|
|
223
|
+
msg = Msg.ERR_FAILED_TO_OPEN_PREFIX + pdt_path
|
|
222
224
|
alerts = self.alert_region.create_alerts(msg, color='danger')
|
|
223
225
|
return alerts
|
|
224
226
|
|
|
@@ -237,27 +239,23 @@ class HomePage(AbstractPage):
|
|
|
237
239
|
# check Femtet state
|
|
238
240
|
connection_state = self.femtet_control.check_femtet_state()
|
|
239
241
|
if connection_state != FemtetState.connected:
|
|
240
|
-
msg =
|
|
241
|
-
'Launch Femtet and Open a project.')
|
|
242
|
+
msg = Msg.ERR_NO_CONNECTION_ESTABLISHED
|
|
242
243
|
alerts = self.alert_region.create_alerts(msg, color='danger', current_alerts=current_alerts)
|
|
243
244
|
return alerts
|
|
244
245
|
|
|
245
246
|
# check selection
|
|
246
247
|
if selection_data is None:
|
|
247
|
-
msg =
|
|
248
|
+
msg = Msg.ERR_NO_SOLUTION_SELECTED
|
|
248
249
|
alerts = self.alert_region.create_alerts(msg, color='danger', current_alerts=current_alerts)
|
|
249
250
|
return alerts
|
|
250
251
|
|
|
251
252
|
try:
|
|
252
253
|
Femtet = self.femtet_control.fem.Femtet
|
|
253
254
|
|
|
254
|
-
|
|
255
255
|
# check model to open is included in current project
|
|
256
256
|
if (self.femtet_control.fem.femprj_path != Femtet.Project) \
|
|
257
257
|
or (self.femtet_control.fem.model_name not in Femtet.GetAnalysisModelNames_py()):
|
|
258
|
-
msg =
|
|
259
|
-
f'Please check opened project. '
|
|
260
|
-
f'For example, not "analysis model only" but your .femprj file.')
|
|
258
|
+
msg = Msg.ERR_NO_SUCH_MODEL_IN_FEMPRJ + f' model name: {self.femtet_control.fem.model_name}'
|
|
261
259
|
alerts = self.alert_region.create_alerts(msg, color='danger', current_alerts=current_alerts)
|
|
262
260
|
return alerts
|
|
263
261
|
|
|
@@ -362,19 +360,19 @@ class HomePage(AbstractPage):
|
|
|
362
360
|
# alert
|
|
363
361
|
new_alerts = current_alerts
|
|
364
362
|
if femprj_path_history_on_history is None:
|
|
365
|
-
msg =
|
|
363
|
+
msg = Msg.WARN_INCONSISTENT_FEMPRJ_PATH
|
|
366
364
|
new_alerts = self.alert_region.create_alerts(msg, 'warning', new_alerts)
|
|
367
365
|
else:
|
|
368
366
|
if not is_same_femprj:
|
|
369
|
-
msg =
|
|
367
|
+
msg = Msg.WARN_INCONSISTENT_FEMPRJ_PATH
|
|
370
368
|
new_alerts = self.alert_region.create_alerts(msg, 'warning', new_alerts)
|
|
371
369
|
|
|
372
370
|
if model_name_on_history is None:
|
|
373
|
-
msg =
|
|
371
|
+
msg = Msg.WARN_INVALID_MODEL_NAME
|
|
374
372
|
new_alerts = self.alert_region.create_alerts(msg, 'warning', new_alerts)
|
|
375
373
|
else:
|
|
376
374
|
if not is_same_model:
|
|
377
|
-
msg =
|
|
375
|
+
msg = Msg.WARN_INCONSISTENT_MODEL_NAME
|
|
378
376
|
new_alerts = self.alert_region.create_alerts(msg, 'warning', new_alerts)
|
|
379
377
|
|
|
380
378
|
if new_alerts == current_alerts:
|
|
@@ -408,7 +406,7 @@ class Tutorial(AbstractPage):
|
|
|
408
406
|
|
|
409
407
|
# switch tutorial mode (always visible)
|
|
410
408
|
self.tutorial_mode_switch = dbc.Checklist(
|
|
411
|
-
[
|
|
409
|
+
[Msg.LABEL_TUTORIAL_MODE_SWITCH],
|
|
412
410
|
id='tutorial-mode-switch',
|
|
413
411
|
switch=True,
|
|
414
412
|
value=False
|
|
@@ -417,17 +415,14 @@ class Tutorial(AbstractPage):
|
|
|
417
415
|
# load sample csv
|
|
418
416
|
self.load_sample_csv_badge = self.create_badge('Click Me!', 'load-sample-csv-badge')
|
|
419
417
|
self.load_sample_csv_button = dbc.Button(
|
|
420
|
-
children=[
|
|
418
|
+
children=[Msg.LABEL_LOAD_SAMPLE_CSV, self.load_sample_csv_badge],
|
|
421
419
|
id='load-sample-csv-button',
|
|
422
420
|
className="position-relative", # need to show badge
|
|
423
421
|
)
|
|
424
422
|
self.load_sample_csv_popover = dbc.Popover(
|
|
425
423
|
children=[
|
|
426
|
-
dbc.PopoverHeader(
|
|
427
|
-
dbc.PopoverBody(
|
|
428
|
-
'Open your optimization result. Then connecting to femtet will start automatically. '
|
|
429
|
-
'Note that in tutorial mode, this button loads the ready-made sample csv and open sample femprj.'
|
|
430
|
-
),
|
|
424
|
+
dbc.PopoverHeader(Msg.LOAD_CSV_POPOVER_HEADER),
|
|
425
|
+
dbc.PopoverBody(Msg.LOAD_CSV_POPOVER_BODY),
|
|
431
426
|
],
|
|
432
427
|
id='load-sample-csv-popover',
|
|
433
428
|
target=self.load_sample_csv_button.id,
|
|
@@ -444,12 +439,10 @@ class Tutorial(AbstractPage):
|
|
|
444
439
|
self.graph_badge = self.create_badge('Choose a Point!', 'graph-badge')
|
|
445
440
|
self.graph_popover = dbc.Popover(
|
|
446
441
|
children=[
|
|
447
|
-
dbc.PopoverHeader(
|
|
442
|
+
dbc.PopoverHeader(Msg.MAIN_GRAPH_POPOVER_HEADER),
|
|
448
443
|
dbc.PopoverBody(
|
|
449
444
|
children=[
|
|
450
|
-
|
|
451
|
-
'Each plot represents single FEM result. '
|
|
452
|
-
'You can pick a result to open the corresponding result in Femtet. ',
|
|
445
|
+
Msg.MAIN_GRAPH_POPOVER_BODY,
|
|
453
446
|
self.graph_badge
|
|
454
447
|
],
|
|
455
448
|
className="position-relative", # need to show badge
|
|
@@ -459,17 +452,15 @@ class Tutorial(AbstractPage):
|
|
|
459
452
|
target=self.main_graph.tabs.id,
|
|
460
453
|
is_open=False,
|
|
461
454
|
placement='bottom',
|
|
455
|
+
hide_arrow=True,
|
|
462
456
|
)
|
|
463
457
|
|
|
464
458
|
# popover and badge of open pdt
|
|
465
459
|
self.open_pdt_badge = self.create_badge('Click Me!', 'open-pdt-badge')
|
|
466
460
|
self.open_pdt_popover = dbc.Popover(
|
|
467
461
|
children=[
|
|
468
|
-
dbc.PopoverHeader(
|
|
469
|
-
dbc.PopoverBody(
|
|
470
|
-
'After pick a point in the main graph, '
|
|
471
|
-
'This button shows the corresponding FEM result in Femtet.'
|
|
472
|
-
),
|
|
462
|
+
dbc.PopoverHeader(Msg.OPEN_PDT_POPOVER_HEADER),
|
|
463
|
+
dbc.PopoverBody(Msg.OPEN_PDT_POPOVER_BODY),
|
|
473
464
|
],
|
|
474
465
|
id='open-pdt-popover',
|
|
475
466
|
target=self.home_page.open_pdt_button.id,
|
|
@@ -479,7 +470,7 @@ class Tutorial(AbstractPage):
|
|
|
479
470
|
# popover of connect-femtet
|
|
480
471
|
self.connect_femtet_popover = dbc.Popover(
|
|
481
472
|
children=[
|
|
482
|
-
dbc.PopoverBody(
|
|
473
|
+
dbc.PopoverBody(Msg.CONNECT_FEMTET_POPOVER_BODY),
|
|
483
474
|
],
|
|
484
475
|
id='connect-femtet-popover',
|
|
485
476
|
target=self.femtet_control.connect_femtet_button.id,
|
|
@@ -487,7 +478,6 @@ class Tutorial(AbstractPage):
|
|
|
487
478
|
placement='bottom',
|
|
488
479
|
)
|
|
489
480
|
|
|
490
|
-
|
|
491
481
|
def setup_layout(self):
|
|
492
482
|
pass
|
|
493
483
|
|
|
@@ -624,28 +614,34 @@ class Tutorial(AbstractPage):
|
|
|
624
614
|
if callback_context.triggered_id is None:
|
|
625
615
|
raise PreventUpdate
|
|
626
616
|
|
|
627
|
-
|
|
617
|
+
# get sample file
|
|
618
|
+
import pyfemtet
|
|
619
|
+
package_root = os.path.dirname(pyfemtet.__file__)
|
|
620
|
+
sample_dir = os.path.join(package_root, 'opt', 'femprj_sample') # FIXME: locale によってパスを変える
|
|
621
|
+
path = os.path.join(sample_dir, 'wat_ex14_parametric_test_result.reccsv')
|
|
628
622
|
|
|
629
623
|
if not os.path.exists(path):
|
|
630
|
-
msg =
|
|
624
|
+
msg = Msg.ERR_SAMPLE_CSV_NOT_FOUND
|
|
631
625
|
alerts = self.home_page.alert_region.create_alerts(msg, color='danger', current_alerts=current_alerts)
|
|
632
626
|
return no_update, no_update, no_update, alerts
|
|
633
|
-
|
|
627
|
+
destination_file = path.replace('wat_ex14_parametric_test_result.reccsv', 'tutorial.csv')
|
|
628
|
+
shutil.copyfile(path, destination_file)
|
|
629
|
+
self.application.history = History(destination_file)
|
|
634
630
|
|
|
635
|
-
source_file = path.replace('
|
|
631
|
+
source_file = path.replace('_test_result.reccsv', '.femprj')
|
|
636
632
|
if not os.path.exists(source_file):
|
|
637
|
-
msg =
|
|
633
|
+
msg = Msg.ERR_SAMPLE_FEMPRJ_NOT_FOUND
|
|
638
634
|
alerts = self.home_page.alert_region.create_alerts(msg, color='danger', current_alerts=current_alerts)
|
|
639
635
|
return no_update, no_update, no_update, alerts
|
|
640
|
-
destination_file =
|
|
636
|
+
destination_file = source_file.replace('wat_ex14_parametric', 'tutorial')
|
|
641
637
|
shutil.copyfile(source_file, destination_file)
|
|
642
638
|
|
|
643
|
-
source_folder = path.replace('
|
|
639
|
+
source_folder = path.replace('_test_result.reccsv', '.Results')
|
|
644
640
|
if not os.path.exists(source_file):
|
|
645
|
-
msg =
|
|
641
|
+
msg = Msg.ERR_FEMPRJ_RESULT_NOT_FOUND
|
|
646
642
|
alerts = self.home_page.alert_region.create_alerts(msg, color='danger', current_alerts=current_alerts)
|
|
647
643
|
return no_update, no_update, no_update, alerts
|
|
648
|
-
destination_folder =
|
|
644
|
+
destination_folder = source_folder.replace('wat_ex14_parametric', 'tutorial')
|
|
649
645
|
shutil.copytree(source_folder, destination_folder, dirs_exist_ok=True)
|
|
650
646
|
|
|
651
647
|
self.application.history.metadata[0] = json.dumps(
|
|
@@ -690,3 +686,19 @@ class Tutorial(AbstractPage):
|
|
|
690
686
|
else:
|
|
691
687
|
current_style.update(part)
|
|
692
688
|
return current_style
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
class PredictionModelPage(AbstractPage):
|
|
692
|
+
""""""
|
|
693
|
+
|
|
694
|
+
def __init__(self, title, rel_url, application):
|
|
695
|
+
from pyfemtet.opt.visualization.process_monitor.application import ProcessMonitorApplication
|
|
696
|
+
self.application: ProcessMonitorApplication = None
|
|
697
|
+
super().__init__(title, rel_url, application)
|
|
698
|
+
|
|
699
|
+
def setup_component(self):
|
|
700
|
+
self.rsm_graph: PredictionModelGraph = PredictionModelGraph()
|
|
701
|
+
self.add_subpage(self.rsm_graph)
|
|
702
|
+
|
|
703
|
+
def setup_layout(self):
|
|
704
|
+
self.layout = self.rsm_graph.layout
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyfemtet
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.14
|
|
4
4
|
Summary: Design parameter optimization using Femtet.
|
|
5
5
|
Home-page: https://github.com/pyfemtet/pyfemtet
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -12,6 +12,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.10
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Requires-Dist: babel (>=2.15.0,<3.0.0)
|
|
15
16
|
Requires-Dist: botorch (>=0.9.5) ; python_version >= "3.12" and python_version < "3.13"
|
|
16
17
|
Requires-Dist: botorch (>=0.9.5,<0.10.0) ; python_version < "3.12"
|
|
17
18
|
Requires-Dist: colorlog (>=6.8.0,<7.0.0)
|