pyfemtet 0.9.6__py3-none-any.whl → 1.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.
Potentially problematic release.
This version of pyfemtet might be problematic. Click here for more details.
- pyfemtet/__init__.py +6 -1
- pyfemtet/_i18n/1. make_pot_and_update_po.bat +8 -0
- pyfemtet/_i18n/2. build_mo.bat +5 -0
- pyfemtet/_i18n/__init__.py +4 -0
- pyfemtet/_i18n/babel.cfg +2 -0
- pyfemtet/_i18n/i18n.py +37 -0
- pyfemtet/_i18n/locales/ja/LC_MESSAGES/messages.mo +0 -0
- pyfemtet/_i18n/locales/ja/LC_MESSAGES/messages.po +1020 -0
- pyfemtet/_i18n/locales/messages.pot +987 -0
- pyfemtet/{_message → _i18n}/messages.py +128 -41
- pyfemtet/_util/closing.py +19 -0
- pyfemtet/_util/dask_util.py +89 -7
- pyfemtet/_util/df_util.py +46 -0
- pyfemtet/_util/excel_macro_util.py +8 -3
- pyfemtet/_util/excel_parse_util.py +43 -23
- pyfemtet/_util/femtet_access_inspection.py +120 -0
- pyfemtet/{_femtet_config_util/autosave.py → _util/femtet_autosave.py} +7 -0
- pyfemtet/_util/femtet_exit.py +105 -0
- pyfemtet/_util/femtet_version.py +20 -0
- pyfemtet/_util/helper.py +103 -0
- pyfemtet/_util/process_util.py +107 -0
- pyfemtet/_util/str_enum.py +44 -0
- pyfemtet/core.py +15 -47
- pyfemtet/dispatch_extensions/__init__.py +8 -11
- pyfemtet/dispatch_extensions/_impl.py +42 -198
- pyfemtet/logger/__init__.py +8 -1
- pyfemtet/logger/_impl.py +5 -6
- pyfemtet/opt/__init__.py +3 -17
- pyfemtet/opt/exceptions.py +45 -0
- pyfemtet/opt/femopt.py +621 -0
- pyfemtet/opt/history/__init__.py +11 -0
- pyfemtet/opt/history/_history.py +1416 -0
- pyfemtet/opt/history/_hypervolume.py +169 -0
- pyfemtet/opt/history/_optimality.py +79 -0
- pyfemtet/opt/interface/__init__.py +17 -24
- pyfemtet/opt/interface/_base_interface.py +222 -0
- pyfemtet/opt/interface/_excel_interface/__init__.py +3 -0
- pyfemtet/opt/interface/_excel_interface/debug-excel-interface.xlsm +0 -0
- pyfemtet/opt/interface/_excel_interface/excel_interface.py +997 -0
- pyfemtet/opt/interface/_femtet_interface/__init__.py +3 -0
- pyfemtet/opt/interface/{_femtet_parametric.py → _femtet_interface/_femtet_parametric.py} +20 -12
- pyfemtet/opt/interface/{_femtet.py → _femtet_interface/femtet_interface.py} +508 -353
- pyfemtet/opt/interface/_femtet_with_nx_interface/__init__.py +5 -0
- pyfemtet/opt/interface/_femtet_with_nx_interface/femtet_with_nx_interface.py +230 -0
- pyfemtet/opt/interface/_femtet_with_nx_interface/model1.prt +0 -0
- pyfemtet/opt/interface/_femtet_with_nx_interface/model1.x_t +98 -0
- pyfemtet/opt/interface/{_femtet_with_nx → _femtet_with_nx_interface}/update_model.py +1 -3
- pyfemtet/opt/interface/_femtet_with_solidworks/__init__.py +5 -0
- pyfemtet/opt/interface/_femtet_with_solidworks/femtet_with_solidworks_interface.py +142 -0
- pyfemtet/opt/interface/_solidworks_interface/__init__.py +5 -0
- pyfemtet/opt/interface/_solidworks_interface/solidworks_interface.py +227 -0
- pyfemtet/opt/interface/_surrogate_model_interface/__init__.py +8 -0
- pyfemtet/opt/interface/_surrogate_model_interface/base_surrogate_interface.py +150 -0
- pyfemtet/opt/interface/_surrogate_model_interface/botorch_interface.py +298 -0
- pyfemtet/opt/interface/_surrogate_model_interface/debug-pof-botorch.reccsv +18 -0
- pyfemtet/opt/interface/_with_excel_settings/__init__.py +61 -0
- pyfemtet/opt/interface/_with_excel_settings/with_excel_settings.py +134 -0
- pyfemtet/opt/meta_script/YAML_Generator.xlsm +0 -0
- pyfemtet/opt/meta_script/__main__.py +58 -36
- pyfemtet/opt/optimizer/__init__.py +7 -9
- pyfemtet/opt/optimizer/_base_optimizer.py +911 -0
- pyfemtet/opt/optimizer/optuna_optimizer/__init__.py +9 -0
- pyfemtet/opt/optimizer/optuna_optimizer/_optuna_attribute.py +63 -0
- pyfemtet/opt/optimizer/optuna_optimizer/_optuna_optimizer.py +796 -0
- pyfemtet/opt/optimizer/optuna_optimizer/_pof_botorch/__init__.py +7 -0
- pyfemtet/opt/optimizer/optuna_optimizer/_pof_botorch/debug-pof-botorch.reccsv +18 -0
- pyfemtet/opt/optimizer/optuna_optimizer/_pof_botorch/enable_nonlinear_constraint.py +244 -0
- pyfemtet/opt/optimizer/optuna_optimizer/_pof_botorch/pof_botorch_sampler.py +1249 -0
- pyfemtet/opt/optimizer/optuna_optimizer/wat_ex14_parametric_jp.femprj +0 -0
- pyfemtet/opt/optimizer/scipy_optimizer/__init__.py +1 -0
- pyfemtet/opt/optimizer/scipy_optimizer/_scipy_optimizer.py +383 -0
- pyfemtet/opt/prediction/__init__.py +7 -0
- pyfemtet/opt/prediction/_botorch_utils.py +133 -0
- pyfemtet/opt/prediction/_gpytorch_modules_extension.py +142 -0
- pyfemtet/opt/prediction/_helper.py +155 -0
- pyfemtet/opt/prediction/_model.py +118 -0
- pyfemtet/opt/problem/problem.py +304 -0
- pyfemtet/opt/problem/variable_manager/__init__.py +20 -0
- pyfemtet/opt/problem/variable_manager/_string_as_expression.py +115 -0
- pyfemtet/opt/problem/variable_manager/_variable_manager.py +295 -0
- pyfemtet/opt/visualization/history_viewer/__main__.py +5 -0
- pyfemtet/opt/visualization/{_base.py → history_viewer/_base_application.py} +18 -13
- pyfemtet/opt/visualization/history_viewer/_common_pages.py +150 -0
- pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/alert_region.py +10 -5
- pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/control_femtet.py +16 -13
- pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/main_graph.py +117 -47
- pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/pm_graph.py +159 -138
- pyfemtet/opt/visualization/history_viewer/_process_monitor/_application.py +173 -0
- pyfemtet/opt/visualization/history_viewer/_process_monitor/_pages.py +291 -0
- pyfemtet/opt/visualization/{_wrapped_components → history_viewer/_wrapped_components}/dbc.py +1 -1
- pyfemtet/opt/visualization/{_wrapped_components → history_viewer/_wrapped_components}/dcc.py +1 -1
- pyfemtet/opt/visualization/{_wrapped_components → history_viewer/_wrapped_components}/html.py +1 -1
- pyfemtet/opt/visualization/history_viewer/result_viewer/__main__.py +5 -0
- pyfemtet/opt/visualization/{result_viewer/application.py → history_viewer/result_viewer/_application.py} +6 -6
- pyfemtet/opt/visualization/{result_viewer/pages.py → history_viewer/result_viewer/_pages.py} +106 -82
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08.csv +18 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08.db +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8.log +45 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_1.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_1.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_10.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_10.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_11.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_11.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_12.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_12.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_13.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_13.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_14.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_14.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_15.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_15.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_16.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_16.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_17.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_17.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_18.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_18.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_19.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_19.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_2.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_2.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_20.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_20.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_3.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_3.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.bgr +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.bnd +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.btr +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.mtl +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.prm +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_5.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_5.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_6.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_6.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_7.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_7.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_8.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_8.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_9.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_9.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.femprj +0 -0
- pyfemtet/opt/visualization/plotter/main_figure_creator.py +536 -0
- pyfemtet/opt/visualization/plotter/pm_graph_creator.py +359 -0
- pyfemtet/opt/worker_status.py +120 -0
- {pyfemtet-0.9.6.dist-info → pyfemtet-1.0.0.dist-info}/METADATA +23 -24
- pyfemtet-1.0.0.dist-info/RECORD +172 -0
- pyfemtet-1.0.0.dist-info/entry_points.txt +3 -0
- pyfemtet/_femtet_config_util/exit.py +0 -59
- pyfemtet/_message/1. make_pot.bat +0 -11
- pyfemtet/_message/2. make_mo.bat +0 -6
- pyfemtet/_message/__init__.py +0 -5
- pyfemtet/_message/babel.cfg +0 -2
- pyfemtet/_message/locales/ja/LC_MESSAGES/messages.mo +0 -0
- pyfemtet/_message/locales/ja/LC_MESSAGES/messages.po +0 -570
- pyfemtet/_message/locales/messages.pot +0 -551
- pyfemtet/_warning.py +0 -87
- pyfemtet/brep/_impl.py +0 -18
- pyfemtet/opt/_femopt.py +0 -1007
- pyfemtet/opt/_femopt_core.py +0 -1169
- pyfemtet/opt/_test_utils/control_femtet.py +0 -39
- pyfemtet/opt/_test_utils/hyper_sphere.py +0 -24
- pyfemtet/opt/_test_utils/record_history.py +0 -130
- pyfemtet/opt/advanced_samples/excel_ui/(ref) original_project.femprj +0 -0
- pyfemtet/opt/advanced_samples/excel_ui/femtet-macro.xlsm +0 -0
- pyfemtet/opt/advanced_samples/excel_ui/pyfemtet-core.py +0 -291
- pyfemtet/opt/advanced_samples/excel_ui/test-pyfemtet-core.cmd +0 -22
- pyfemtet/opt/advanced_samples/restart/gal_ex13_parametric.femprj +0 -0
- pyfemtet/opt/advanced_samples/restart/gal_ex13_parametric_restart.py +0 -99
- pyfemtet/opt/advanced_samples/restart/gal_ex13_parametric_restart_jp.py +0 -102
- pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_create_training_data.py +0 -60
- pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_create_training_data_jp.py +0 -57
- pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_optimize_with_surrogate.py +0 -100
- pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_optimize_with_surrogate_jp.py +0 -90
- pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_parametric.femprj +0 -0
- pyfemtet/opt/interface/_base.py +0 -101
- pyfemtet/opt/interface/_excel_interface.py +0 -984
- pyfemtet/opt/interface/_femtet_excel.py +0 -141
- pyfemtet/opt/interface/_femtet_with_nx/__init__.py +0 -3
- pyfemtet/opt/interface/_femtet_with_nx/_interface.py +0 -178
- pyfemtet/opt/interface/_femtet_with_sldworks.py +0 -298
- pyfemtet/opt/interface/_surrogate/__init__.py +0 -5
- pyfemtet/opt/interface/_surrogate/_base.py +0 -129
- pyfemtet/opt/interface/_surrogate/_chaospy.py +0 -71
- pyfemtet/opt/interface/_surrogate/_singletaskgp.py +0 -71
- pyfemtet/opt/interface/_surrogate_excel.py +0 -102
- pyfemtet/opt/optimizer/_base.py +0 -376
- pyfemtet/opt/optimizer/_optuna/_botorch_patch/enable_nonlinear_constraint.py +0 -220
- pyfemtet/opt/optimizer/_optuna/_optuna.py +0 -434
- pyfemtet/opt/optimizer/_optuna/_pof_botorch.py +0 -1914
- pyfemtet/opt/optimizer/_scipy.py +0 -159
- pyfemtet/opt/optimizer/_scipy_scalar.py +0 -127
- pyfemtet/opt/optimizer/parameter.py +0 -113
- pyfemtet/opt/prediction/_base.py +0 -61
- pyfemtet/opt/prediction/single_task_gp.py +0 -119
- pyfemtet/opt/samples/femprj_sample/ParametricIF.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/ParametricIF.py +0 -29
- pyfemtet/opt/samples/femprj_sample/ParametricIF_test_result.reccsv +0 -13
- pyfemtet/opt/samples/femprj_sample/cad_ex01_NX.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/cad_ex01_NX.prt +0 -0
- pyfemtet/opt/samples/femprj_sample/cad_ex01_NX.py +0 -135
- pyfemtet/opt/samples/femprj_sample/cad_ex01_NX_test_result.reccsv +0 -23
- pyfemtet/opt/samples/femprj_sample/cad_ex01_SW.SLDPRT +0 -0
- pyfemtet/opt/samples/femprj_sample/cad_ex01_SW.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/cad_ex01_SW.py +0 -131
- pyfemtet/opt/samples/femprj_sample/cad_ex01_SW_test_result.reccsv +0 -23
- pyfemtet/opt/samples/femprj_sample/constrained_pipe.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/constrained_pipe.py +0 -96
- pyfemtet/opt/samples/femprj_sample/constrained_pipe_test_result.reccsv +0 -13
- pyfemtet/opt/samples/femprj_sample/gal_ex58_parametric.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/gal_ex58_parametric.py +0 -74
- pyfemtet/opt/samples/femprj_sample/gal_ex58_parametric_test_result.reccsv +0 -13
- pyfemtet/opt/samples/femprj_sample/gau_ex08_parametric.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/gau_ex08_parametric.py +0 -58
- pyfemtet/opt/samples/femprj_sample/gau_ex08_parametric_test_result.reccsv +0 -23
- pyfemtet/opt/samples/femprj_sample/gau_ex12_parametric.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/gau_ex12_parametric.py +0 -52
- pyfemtet/opt/samples/femprj_sample/her_ex40_parametric.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/her_ex40_parametric.py +0 -138
- pyfemtet/opt/samples/femprj_sample/her_ex40_parametric_test_result.reccsv +0 -18
- pyfemtet/opt/samples/femprj_sample/paswat_ex1_parametric.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/paswat_ex1_parametric.py +0 -60
- pyfemtet/opt/samples/femprj_sample/paswat_ex1_parametric_parallel.py +0 -61
- pyfemtet/opt/samples/femprj_sample/paswat_ex1_parametric_test_result.reccsv +0 -18
- pyfemtet/opt/samples/femprj_sample/wat_ex14_parametric.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/wat_ex14_parametric.py +0 -58
- pyfemtet/opt/samples/femprj_sample/wat_ex14_parametric_parallel.py +0 -58
- pyfemtet/opt/samples/femprj_sample/wat_ex14_parametric_test_result.reccsv +0 -18
- pyfemtet/opt/samples/femprj_sample_jp/ParametricIF_jp.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample_jp/ParametricIF_jp.py +0 -29
- pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_NX_jp.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_NX_jp.py +0 -129
- pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_SW_jp.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_SW_jp.py +0 -125
- pyfemtet/opt/samples/femprj_sample_jp/constrained_pipe_jp.py +0 -93
- pyfemtet/opt/samples/femprj_sample_jp/gal_ex58_parametric_jp.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample_jp/gal_ex58_parametric_jp.py +0 -70
- pyfemtet/opt/samples/femprj_sample_jp/gau_ex08_parametric_jp.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample_jp/gau_ex08_parametric_jp.py +0 -57
- pyfemtet/opt/samples/femprj_sample_jp/gau_ex12_parametric_jp.py +0 -52
- pyfemtet/opt/samples/femprj_sample_jp/her_ex40_parametric_jp.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample_jp/her_ex40_parametric_jp.py +0 -138
- pyfemtet/opt/samples/femprj_sample_jp/paswat_ex1_parametric_jp.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample_jp/paswat_ex1_parametric_jp.py +0 -58
- pyfemtet/opt/samples/femprj_sample_jp/paswat_ex1_parametric_parallel_jp.py +0 -59
- pyfemtet/opt/samples/femprj_sample_jp/wat_ex14_parametric_jp.py +0 -56
- pyfemtet/opt/samples/femprj_sample_jp/wat_ex14_parametric_parallel_jp.py +0 -56
- pyfemtet/opt/visualization/_complex_components/main_figure_creator.py +0 -332
- pyfemtet/opt/visualization/_complex_components/pm_graph_creator.py +0 -201
- pyfemtet/opt/visualization/_process_monitor/application.py +0 -226
- pyfemtet/opt/visualization/_process_monitor/pages.py +0 -406
- pyfemtet/opt/visualization/_wrapped_components/__init__.py +0 -0
- pyfemtet/opt/visualization/result_viewer/__init__.py +0 -0
- pyfemtet-0.9.6.dist-info/RECORD +0 -158
- pyfemtet-0.9.6.dist-info/entry_points.txt +0 -3
- /pyfemtet/{_femtet_config_util → opt/problem}/__init__.py +0 -0
- /pyfemtet/{brep → opt/visualization/history_viewer}/__init__.py +0 -0
- /pyfemtet/opt/{_test_utils → visualization/history_viewer/_complex_components}/__init__.py +0 -0
- /pyfemtet/opt/{optimizer/_optuna → visualization/history_viewer/_process_monitor}/__init__.py +0 -0
- /pyfemtet/opt/{optimizer/_optuna/_botorch_patch → visualization/history_viewer/_wrapped_components}/__init__.py +0 -0
- /pyfemtet/opt/visualization/{_wrapped_components → history_viewer/_wrapped_components}/str_enum.py +0 -0
- /pyfemtet/opt/visualization/{result_viewer → history_viewer/result_viewer}/.gitignore +0 -0
- /pyfemtet/opt/visualization/{_complex_components → history_viewer/result_viewer}/__init__.py +0 -0
- /pyfemtet/opt/visualization/{_process_monitor → plotter}/__init__.py +0 -0
- /pyfemtet/opt/{samples/femprj_sample_jp/wat_ex14_parametric_jp.femprj → wat_ex14_parametric_jp.femprj} +0 -0
- {pyfemtet-0.9.6.dist-info → pyfemtet-1.0.0.dist-info}/LICENSE +0 -0
- {pyfemtet-0.9.6.dist-info → pyfemtet-1.0.0.dist-info}/LICENSE_THIRD_PARTY.txt +0 -0
- {pyfemtet-0.9.6.dist-info → pyfemtet-1.0.0.dist-info}/WHEEL +0 -0
pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/pm_graph.py
RENAMED
|
@@ -1,29 +1,27 @@
|
|
|
1
|
-
# type hint
|
|
2
|
-
from dash.development.base_component import Component
|
|
3
|
-
|
|
4
1
|
# callback
|
|
5
2
|
from dash import Output, Input, State, no_update, callback_context, ALL
|
|
6
3
|
from dash.exceptions import PreventUpdate
|
|
7
4
|
|
|
8
5
|
# components
|
|
9
|
-
from
|
|
10
|
-
from pyfemtet.opt.visualization._wrapped_components import
|
|
6
|
+
from pyfemtet.opt.visualization.history_viewer._wrapped_components import html
|
|
7
|
+
from pyfemtet.opt.visualization.history_viewer._wrapped_components import dcc, dbc
|
|
11
8
|
|
|
12
9
|
# graph
|
|
13
|
-
import pandas as pd
|
|
14
|
-
# import plotly.express as px
|
|
15
10
|
import plotly.graph_objs as go
|
|
16
11
|
|
|
17
12
|
# the others
|
|
18
13
|
from enum import Enum, auto
|
|
19
|
-
import os
|
|
20
|
-
import base64
|
|
21
|
-
import json
|
|
22
|
-
import numpy as np
|
|
23
14
|
|
|
24
|
-
from pyfemtet.opt.
|
|
25
|
-
from pyfemtet.opt.
|
|
26
|
-
from pyfemtet.
|
|
15
|
+
from pyfemtet.opt.prediction._model import *
|
|
16
|
+
from pyfemtet.opt.prediction._helper import *
|
|
17
|
+
from pyfemtet.opt.visualization.plotter.pm_graph_creator import plot2d, plot3d
|
|
18
|
+
from pyfemtet.opt.visualization.history_viewer._base_application import AbstractPage, logger
|
|
19
|
+
from pyfemtet._i18n import Msg
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
'PredictionModelGraph'
|
|
24
|
+
]
|
|
27
25
|
|
|
28
26
|
|
|
29
27
|
FLEXBOX_STYLE_ALLOW_VERTICAL_FILL = {
|
|
@@ -67,7 +65,7 @@ class PredictionModelGraph(AbstractPage):
|
|
|
67
65
|
redraw = auto()
|
|
68
66
|
|
|
69
67
|
def __init__(self):
|
|
70
|
-
self.
|
|
68
|
+
self.pyfemtet_model: PyFemtetModel = PyFemtetModel()
|
|
71
69
|
super().__init__()
|
|
72
70
|
|
|
73
71
|
def setup_component(self):
|
|
@@ -106,9 +104,11 @@ class PredictionModelGraph(AbstractPage):
|
|
|
106
104
|
self.command_manager_prop = 'data-command-manager'
|
|
107
105
|
self.command_manager = html.Data(**{self.command_manager_prop: self.CommandState.ready.value})
|
|
108
106
|
self.fit_rsm_button_spinner = dbc.Spinner(size='sm', spinner_style={'display': 'none'})
|
|
109
|
-
self.fit_rsm_button = dbc.Button([self.fit_rsm_button_spinner, Msg.LABEL_OF_CREATE_PREDICTION_MODEL_BUTTON],
|
|
107
|
+
self.fit_rsm_button = dbc.Button([self.fit_rsm_button_spinner, Msg.LABEL_OF_CREATE_PREDICTION_MODEL_BUTTON],
|
|
108
|
+
color='success')
|
|
110
109
|
self.redraw_graph_button_spinner = dbc.Spinner(size='sm', spinner_style={'display': 'none'})
|
|
111
|
-
self.redraw_graph_button = dbc.Button([self.redraw_graph_button_spinner,
|
|
110
|
+
self.redraw_graph_button = dbc.Button([self.redraw_graph_button_spinner,
|
|
111
|
+
Msg.LABEL_OF_REDRAW_PREDICTION_MODEL_GRAPH_BUTTON])
|
|
112
112
|
|
|
113
113
|
# # set data length (to notify data updated to application)
|
|
114
114
|
# self.data_length_prop = 'data-df-length' # must start with "data-"
|
|
@@ -150,9 +150,36 @@ class PredictionModelGraph(AbstractPage):
|
|
|
150
150
|
)
|
|
151
151
|
|
|
152
152
|
dropdown_rows = [
|
|
153
|
-
dbc.Row([
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
dbc.Row([
|
|
154
|
+
dbc.Col(html.Span(Msg.LABEL_OF_AXIS1_SELECTION),
|
|
155
|
+
align='center',
|
|
156
|
+
style={'text-align': 'end'}, width=2
|
|
157
|
+
),
|
|
158
|
+
dbc.Col(self.axis_controllers[0])
|
|
159
|
+
]),
|
|
160
|
+
dbc.Row(
|
|
161
|
+
[
|
|
162
|
+
dbc.Col(
|
|
163
|
+
html.Span(Msg.LABEL_OF_AXIS2_SELECTION),
|
|
164
|
+
align='center',
|
|
165
|
+
style={'text-align': 'end'},
|
|
166
|
+
width=2
|
|
167
|
+
),
|
|
168
|
+
dbc.Col(self.axis_controllers[1])
|
|
169
|
+
],
|
|
170
|
+
id='prm-axis-2-dropdown'
|
|
171
|
+
),
|
|
172
|
+
dbc.Row(
|
|
173
|
+
[
|
|
174
|
+
dbc.Col(
|
|
175
|
+
html.Span(Msg.LABEL_OF_AXIS3_SELECTION),
|
|
176
|
+
align='center',
|
|
177
|
+
style={'text-align': 'end'},
|
|
178
|
+
width=2
|
|
179
|
+
),
|
|
180
|
+
dbc.Col(self.axis_controllers[2])
|
|
181
|
+
]
|
|
182
|
+
),
|
|
156
183
|
]
|
|
157
184
|
|
|
158
185
|
self.card_footer = dbc.CardFooter(
|
|
@@ -217,8 +244,10 @@ class PredictionModelGraph(AbstractPage):
|
|
|
217
244
|
)
|
|
218
245
|
def disable_fit_button(_1, _2, state1, state2, switch_options):
|
|
219
246
|
# spinner visibility
|
|
220
|
-
if 'display' in state1.keys():
|
|
221
|
-
|
|
247
|
+
if 'display' in state1.keys():
|
|
248
|
+
state1.pop('display')
|
|
249
|
+
if 'display' in state2.keys():
|
|
250
|
+
state2.pop('display')
|
|
222
251
|
|
|
223
252
|
# recalc or redraw
|
|
224
253
|
if callback_context.triggered_id == self.fit_rsm_button.id:
|
|
@@ -253,14 +282,17 @@ class PredictionModelGraph(AbstractPage):
|
|
|
253
282
|
if self.application.history is None:
|
|
254
283
|
return self.CommandState.redraw.value, no_update # error handling in the next `redraw_graph()` callback
|
|
255
284
|
|
|
256
|
-
# check
|
|
257
|
-
if len(self.
|
|
285
|
+
# check df
|
|
286
|
+
if len(self.application.get_df()) == 0:
|
|
258
287
|
return self.CommandState.redraw.value, no_update # error handling in the next `redraw_graph()` callback
|
|
259
288
|
|
|
260
289
|
# create model
|
|
261
|
-
|
|
290
|
+
model = SingleTaskGPModel()
|
|
291
|
+
self.pyfemtet_model.update_model(model)
|
|
292
|
+
self.pyfemtet_model.fit(
|
|
262
293
|
self.application.history,
|
|
263
|
-
self.
|
|
294
|
+
self.application.get_df(),
|
|
295
|
+
**{}
|
|
264
296
|
)
|
|
265
297
|
|
|
266
298
|
return self.CommandState.redraw.value, no_update
|
|
@@ -269,18 +301,34 @@ class PredictionModelGraph(AbstractPage):
|
|
|
269
301
|
@app.callback(
|
|
270
302
|
Output(self.graph, 'figure'),
|
|
271
303
|
Output(self.command_manager, self.command_manager_prop),
|
|
272
|
-
#
|
|
304
|
+
# To determine whether Process Monitor should update
|
|
305
|
+
# the graph, the main graph remembers the current
|
|
306
|
+
# amount of data.
|
|
307
|
+
# Output(self.data_length.id, self.data_length_prop),
|
|
273
308
|
Input(self.command_manager, self.command_manager_prop),
|
|
274
309
|
State(self.tabs, 'active_tab'),
|
|
275
310
|
State(self.axis1_prm_dropdown, 'label'),
|
|
276
311
|
State(self.axis2_prm_dropdown, 'label'),
|
|
277
312
|
State(self.axis3_obj_dropdown, 'label'),
|
|
278
313
|
State(self.slider_container, 'children'), # for callback chain
|
|
314
|
+
State({'type': 'prm-slider', 'index': ALL}, 'id'),
|
|
279
315
|
State({'type': 'prm-slider', 'index': ALL}, 'value'),
|
|
316
|
+
State({'type': 'prm-slider', 'index': ALL}, 'marks'),
|
|
280
317
|
State(self.switch_3d, 'value'),
|
|
281
318
|
prevent_initial_call=True,
|
|
282
319
|
)
|
|
283
|
-
def redraw_graph(
|
|
320
|
+
def redraw_graph(
|
|
321
|
+
command,
|
|
322
|
+
_1,
|
|
323
|
+
axis1_label,
|
|
324
|
+
axis2_label,
|
|
325
|
+
axis3_label,
|
|
326
|
+
_2,
|
|
327
|
+
prm_ids,
|
|
328
|
+
prm_values,
|
|
329
|
+
prm_slider_marks,
|
|
330
|
+
is_3d
|
|
331
|
+
):
|
|
284
332
|
# just in case
|
|
285
333
|
if callback_context.triggered_id is None:
|
|
286
334
|
raise PreventUpdate
|
|
@@ -293,42 +341,58 @@ class PredictionModelGraph(AbstractPage):
|
|
|
293
341
|
if self.application.history is None:
|
|
294
342
|
logger.error(Msg.ERR_NO_HISTORY_SELECTED)
|
|
295
343
|
return no_update, self.CommandState.ready.value # to re-enable buttons, fire callback chain
|
|
296
|
-
prm_names = self.application.history.prm_names
|
|
344
|
+
# prm_names = self.application.history.prm_names
|
|
297
345
|
|
|
298
346
|
# check history
|
|
299
|
-
if len(self.
|
|
347
|
+
if len(self.application.get_df()) == 0:
|
|
300
348
|
logger.error(Msg.ERR_NO_FEM_RESULT)
|
|
301
349
|
return no_update, self.CommandState.ready.value # to re-enable buttons, fire callback chain
|
|
302
350
|
|
|
303
351
|
# check fit
|
|
304
|
-
if not hasattr(self.
|
|
352
|
+
if not hasattr(self.pyfemtet_model, 'current_model'):
|
|
305
353
|
logger.error(Msg.ERR_NO_PREDICTION_MODEL)
|
|
306
354
|
return no_update, self.CommandState.ready.value # to re-enable buttons, fire callback chain
|
|
307
355
|
|
|
308
|
-
|
|
309
|
-
|
|
356
|
+
# create params
|
|
357
|
+
params = dict()
|
|
358
|
+
for prm_id, slider_value, slider_marks in zip(prm_ids, prm_values, prm_slider_marks):
|
|
310
359
|
|
|
311
|
-
|
|
312
|
-
idx1 = prm_names.index(axis1_label) if axis1_label in prm_names else None
|
|
313
|
-
idx2 = prm_names.index(axis2_label) if axis2_label in prm_names else None
|
|
360
|
+
prm_name = prm_id['index']
|
|
314
361
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
prm_values[idx1] = None
|
|
318
|
-
if idx2 is not None:
|
|
319
|
-
prm_values[idx2] = None
|
|
362
|
+
if self.application.history.is_numerical_parameter(prm_name):
|
|
363
|
+
value = slider_value
|
|
320
364
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
365
|
+
# categorical parameters are encoded as an integer, so restore them here.
|
|
366
|
+
elif self.application.history.is_categorical_parameter(prm_name):
|
|
367
|
+
value = slider_marks[str(slider_value)]
|
|
324
368
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
369
|
+
else:
|
|
370
|
+
raise NotImplementedError
|
|
371
|
+
|
|
372
|
+
params.update({prm_name: value})
|
|
373
|
+
|
|
374
|
+
if is_3d:
|
|
375
|
+
fig = plot3d(
|
|
376
|
+
history=self.application.history,
|
|
377
|
+
prm_name1=axis1_label,
|
|
378
|
+
prm_name2=axis2_label,
|
|
379
|
+
params=params,
|
|
380
|
+
obj_name=axis3_label,
|
|
381
|
+
df=self.application.get_df(),
|
|
382
|
+
pyfemtet_model=self.pyfemtet_model,
|
|
383
|
+
n=20,
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
else:
|
|
387
|
+
fig = plot2d(
|
|
388
|
+
history=self.application.history,
|
|
389
|
+
prm_name1=axis1_label,
|
|
390
|
+
params=params,
|
|
391
|
+
obj_name=axis3_label,
|
|
392
|
+
df=self.application.get_df(),
|
|
393
|
+
pyfemtet_model=self.pyfemtet_model,
|
|
394
|
+
n=200,
|
|
395
|
+
)
|
|
332
396
|
|
|
333
397
|
return fig, self.CommandState.ready.value
|
|
334
398
|
|
|
@@ -404,32 +468,54 @@ class PredictionModelGraph(AbstractPage):
|
|
|
404
468
|
sliders = []
|
|
405
469
|
slider_values = {}
|
|
406
470
|
for prm_name in self.application.history.prm_names:
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
471
|
+
|
|
472
|
+
if self.application.history.is_numerical_parameter(prm_name):
|
|
473
|
+
lb, ub = get_bounds_containing_entire_bounds(
|
|
474
|
+
self.application.get_df(),
|
|
475
|
+
prm_name,
|
|
476
|
+
)
|
|
477
|
+
|
|
478
|
+
# create slider
|
|
479
|
+
value = (lb + ub) / 2
|
|
480
|
+
slider = dcc.Slider(
|
|
481
|
+
lb,
|
|
482
|
+
ub,
|
|
483
|
+
marks=None,
|
|
484
|
+
value=value,
|
|
485
|
+
id={'type': 'prm-slider', 'index': prm_name},
|
|
486
|
+
tooltip={"placement": "bottom", "always_visible": True},
|
|
487
|
+
)
|
|
488
|
+
|
|
489
|
+
elif self.application.history.is_categorical_parameter(prm_name):
|
|
490
|
+
choices: set = get_choices_containing_entire_bounds(
|
|
491
|
+
self.application.get_df(),
|
|
492
|
+
prm_name,
|
|
493
|
+
)
|
|
494
|
+
|
|
495
|
+
choices: tuple = tuple(choices)
|
|
496
|
+
|
|
497
|
+
value = choices[0]
|
|
498
|
+
slider = dcc.Slider(
|
|
499
|
+
0,
|
|
500
|
+
len(choices),
|
|
501
|
+
step=None,
|
|
502
|
+
marks={i: choice for i, choice in enumerate(choices)},
|
|
503
|
+
value=0,
|
|
504
|
+
id={'type': 'prm-slider', 'index': prm_name},
|
|
505
|
+
tooltip={"placement": "bottom", "always_visible": True},
|
|
506
|
+
included=False,
|
|
507
|
+
)
|
|
508
|
+
|
|
509
|
+
else:
|
|
510
|
+
raise NotImplementedError
|
|
511
|
+
|
|
419
512
|
slider_values.update({prm_name: value})
|
|
420
513
|
stack = dbc.Stack(
|
|
421
514
|
id={'type': 'prm-slider-stack', 'index': prm_name},
|
|
422
515
|
style={'display': 'inline'},
|
|
423
516
|
children=[
|
|
424
517
|
html.Div(f'{prm_name}: '),
|
|
425
|
-
|
|
426
|
-
lb,
|
|
427
|
-
ub,
|
|
428
|
-
marks=None,
|
|
429
|
-
value=value,
|
|
430
|
-
id={'type': 'prm-slider', 'index': prm_name},
|
|
431
|
-
tooltip={"placement": "bottom", "always_visible": True},
|
|
432
|
-
)
|
|
518
|
+
slider
|
|
433
519
|
]
|
|
434
520
|
)
|
|
435
521
|
sliders.append(stack)
|
|
@@ -477,7 +563,8 @@ class PredictionModelGraph(AbstractPage):
|
|
|
477
563
|
(ax1_label_key := 1): no_update,
|
|
478
564
|
(ax2_label_key := 2): no_update,
|
|
479
565
|
(ax3_label_key := 3): no_update,
|
|
480
|
-
(slider_style_list_key := 4): [(style.update({'display': 'inline'}), style)[1]
|
|
566
|
+
(slider_style_list_key := 4): [(style.update({'display': 'inline'}), style)[1]
|
|
567
|
+
for style in current_styles],
|
|
481
568
|
(ax2_hidden := 5): False,
|
|
482
569
|
}
|
|
483
570
|
|
|
@@ -508,14 +595,12 @@ class PredictionModelGraph(AbstractPage):
|
|
|
508
595
|
if new_label == current_ax2_label:
|
|
509
596
|
ret[ax2_label_key] = current_ax1_label
|
|
510
597
|
|
|
511
|
-
|
|
512
598
|
# ax2
|
|
513
599
|
elif callback_context.triggered_id['type'] == 'axis2-dropdown-menu-item':
|
|
514
600
|
ret[ax2_label_key] = new_label
|
|
515
601
|
if new_label == current_ax1_label:
|
|
516
602
|
ret[ax1_label_key] = current_ax2_label
|
|
517
603
|
|
|
518
|
-
|
|
519
604
|
# ax3
|
|
520
605
|
elif callback_context.triggered_id['type'] == 'axis3-dropdown-menu-item':
|
|
521
606
|
ret[ax3_label_key] = new_label
|
|
@@ -545,67 +630,3 @@ class PredictionModelGraph(AbstractPage):
|
|
|
545
630
|
ret[slider_style_list_key][idx] = current_styles[idx]
|
|
546
631
|
|
|
547
632
|
return tuple(ret.values())
|
|
548
|
-
|
|
549
|
-
def create_formatted_parameter(self, row) -> Component:
|
|
550
|
-
meta_columns = self.application.history.meta_columns
|
|
551
|
-
pd.options.display.float_format = '{:.4e}'.format
|
|
552
|
-
parameters = row.iloc[:, np.where(np.array(meta_columns) == 'prm')[0]]
|
|
553
|
-
names = parameters.columns
|
|
554
|
-
values = [f'{value:.3e}' for value in parameters.values.ravel()]
|
|
555
|
-
data = pd.DataFrame(dict(
|
|
556
|
-
name=names, value=values
|
|
557
|
-
))
|
|
558
|
-
table = dash_table.DataTable(
|
|
559
|
-
columns=[{'name': col, 'id': col} for col in data.columns],
|
|
560
|
-
data=data.to_dict('records')
|
|
561
|
-
)
|
|
562
|
-
return table
|
|
563
|
-
|
|
564
|
-
def create_image_content_if_femtet(self, trial) -> Component:
|
|
565
|
-
img_url = None
|
|
566
|
-
meta_columns = self.application.history.meta_columns
|
|
567
|
-
if meta_columns[0] != '':
|
|
568
|
-
extra_data = json.loads(meta_columns[0])
|
|
569
|
-
if 'femprj_path' in extra_data:
|
|
570
|
-
# get img path
|
|
571
|
-
femprj_path = extra_data['femprj_path']
|
|
572
|
-
model_name = extra_data['model_name']
|
|
573
|
-
femprj_result_dir = femprj_path.replace('.femprj', '.Results')
|
|
574
|
-
img_path = os.path.join(femprj_result_dir, f'{model_name}_trial{trial}.jpg')
|
|
575
|
-
if os.path.exists(img_path):
|
|
576
|
-
# create encoded image
|
|
577
|
-
with open(img_path, 'rb') as f:
|
|
578
|
-
content = f.read()
|
|
579
|
-
encoded_image = base64.b64encode(content).decode('utf-8')
|
|
580
|
-
img_url = 'data:image/jpeg;base64, ' + encoded_image
|
|
581
|
-
return html.Img(src=img_url, style={"width": "200px"}) if img_url is not None else html.Div()
|
|
582
|
-
|
|
583
|
-
# def get_fig_by_tab_id(self, tab_id, with_length=False):
|
|
584
|
-
# # If the history is not loaded, do nothing
|
|
585
|
-
# if self.application.history is None:
|
|
586
|
-
# raise PreventUpdate
|
|
587
|
-
#
|
|
588
|
-
# # else, get creator by tab_id
|
|
589
|
-
# if tab_id == 'default':
|
|
590
|
-
# creator = self.figure_creators[0]['creator']
|
|
591
|
-
# else:
|
|
592
|
-
# creators = [d['creator'] for d in self.figure_creators if d['tab_id'] == tab_id]
|
|
593
|
-
# if len(creators) == 0:
|
|
594
|
-
# raise PreventUpdate
|
|
595
|
-
# creator = creators[0]
|
|
596
|
-
#
|
|
597
|
-
# # create figure
|
|
598
|
-
# df = self.data_accessor()
|
|
599
|
-
# fig = creator(self.application.history, df)
|
|
600
|
-
# if with_length:
|
|
601
|
-
# return fig, len(df)
|
|
602
|
-
# else:
|
|
603
|
-
# return fig
|
|
604
|
-
|
|
605
|
-
def data_accessor(self) -> pd.DataFrame:
|
|
606
|
-
from pyfemtet.opt.visualization._process_monitor.application import ProcessMonitorApplication
|
|
607
|
-
if isinstance(self.application, ProcessMonitorApplication):
|
|
608
|
-
df = self.application.local_data
|
|
609
|
-
else:
|
|
610
|
-
df = self.application.history.get_df(valid_only=True) # TODO: prediction グラフで infeasible な結果を反映する
|
|
611
|
-
return df
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
from time import sleep
|
|
3
|
+
from threading import Thread
|
|
4
|
+
|
|
5
|
+
from flask import jsonify
|
|
6
|
+
|
|
7
|
+
from pyfemtet.logger import *
|
|
8
|
+
from pyfemtet._util.df_util import *
|
|
9
|
+
|
|
10
|
+
from pyfemtet.opt.worker_status import *
|
|
11
|
+
from pyfemtet.opt.visualization.history_viewer._base_application import *
|
|
12
|
+
from pyfemtet.opt.visualization.history_viewer._common_pages import *
|
|
13
|
+
from pyfemtet.opt.visualization.history_viewer._process_monitor._pages import *
|
|
14
|
+
|
|
15
|
+
from pyfemtet._i18n import Msg
|
|
16
|
+
|
|
17
|
+
logger = get_module_logger('opt.femopt', False)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class MonitorHostRecord:
|
|
21
|
+
|
|
22
|
+
def __init__(self):
|
|
23
|
+
self.info = dict()
|
|
24
|
+
|
|
25
|
+
def set(self, host, port):
|
|
26
|
+
self.info.update(dict(host=host, port=port))
|
|
27
|
+
|
|
28
|
+
def get(self):
|
|
29
|
+
return self.info
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ProcessMonitorApplication(PyFemtetApplicationBase):
|
|
33
|
+
""""""
|
|
34
|
+
"""
|
|
35
|
+
+------+--------+
|
|
36
|
+
| side | con- |
|
|
37
|
+
| bar | tent |
|
|
38
|
+
+--^---+--^-----+
|
|
39
|
+
│ └─ pages (dict(href: str = layout: Component))
|
|
40
|
+
└──────── nav_links (dict(order: float) = NavLink)
|
|
41
|
+
|
|
42
|
+
Accessible members:
|
|
43
|
+
- history: History
|
|
44
|
+
└ local_df: pd.DataFrame
|
|
45
|
+
- app: Dash
|
|
46
|
+
- local_entire_status_int: int <----------------> femopt.statue: OptimizationStatus(Actor)
|
|
47
|
+
- local_worker_status_int_list: List[int] <-----> femopt.opt.statue: List[OptimizationStatus(Actor)]
|
|
48
|
+
^
|
|
49
|
+
|
|
|
50
|
+
sync "while" statement in start_server()
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
DEFAULT_PORT = 8080
|
|
54
|
+
|
|
55
|
+
def __init__(
|
|
56
|
+
self,
|
|
57
|
+
history,
|
|
58
|
+
status,
|
|
59
|
+
worker_addresses,
|
|
60
|
+
worker_names,
|
|
61
|
+
worker_status_list,
|
|
62
|
+
is_debug=False,
|
|
63
|
+
):
|
|
64
|
+
super().__init__(
|
|
65
|
+
title='PyFemtet Monitor',
|
|
66
|
+
subtitle='visualize optimization progress',
|
|
67
|
+
history=history,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
self.is_debug = is_debug
|
|
71
|
+
|
|
72
|
+
# register arguments
|
|
73
|
+
self._local_data = history.get_df() # scheduler への負荷を避けるためアクセスは while loop の中で行う
|
|
74
|
+
self.worker_names: List[str] = worker_names
|
|
75
|
+
self.worker_addresses = worker_addresses
|
|
76
|
+
self.entire_status: WorkerStatus = status # include actor
|
|
77
|
+
self.worker_status_list: List[WorkerStatus] = worker_status_list # include actor
|
|
78
|
+
|
|
79
|
+
def setup_callback(self, debug=False):
|
|
80
|
+
if not debug:
|
|
81
|
+
super().setup_callback()
|
|
82
|
+
|
|
83
|
+
@self.server.route('/interrupt')
|
|
84
|
+
def some_command():
|
|
85
|
+
|
|
86
|
+
# If the entire_state < INTERRUPTING, set INTERRUPTING
|
|
87
|
+
if self.entire_status.value < WorkerStatus.interrupting:
|
|
88
|
+
self.entire_status.value = WorkerStatus.interrupting
|
|
89
|
+
result = {"message": "Interrupting signal emitted successfully."}
|
|
90
|
+
|
|
91
|
+
else:
|
|
92
|
+
result = {"message": "Interrupting signal is already emitted."}
|
|
93
|
+
|
|
94
|
+
return jsonify(result)
|
|
95
|
+
|
|
96
|
+
def start_server(self, host=None, port=None, host_record=None):
|
|
97
|
+
|
|
98
|
+
host = host or 'localhost'
|
|
99
|
+
port = port or self.DEFAULT_PORT
|
|
100
|
+
|
|
101
|
+
# dash app server を daemon thread で起動
|
|
102
|
+
server_thread = Thread(
|
|
103
|
+
target=self.run,
|
|
104
|
+
args=(host, port,),
|
|
105
|
+
kwargs=dict(host_record=host_record),
|
|
106
|
+
daemon=True,
|
|
107
|
+
)
|
|
108
|
+
server_thread.start()
|
|
109
|
+
|
|
110
|
+
while True:
|
|
111
|
+
# df を actor から application に反映する
|
|
112
|
+
self._local_data = self.history.get_df()
|
|
113
|
+
|
|
114
|
+
# terminate_all 指令があれば flask server をホストするプロセスごと終了する
|
|
115
|
+
if self.entire_status.value >= self.entire_status.terminated:
|
|
116
|
+
# monitor の worker status 更新を行う時間を待つ
|
|
117
|
+
sleep(1)
|
|
118
|
+
break
|
|
119
|
+
|
|
120
|
+
# interval
|
|
121
|
+
sleep(1)
|
|
122
|
+
|
|
123
|
+
return 0 # take server down with me
|
|
124
|
+
|
|
125
|
+
@staticmethod
|
|
126
|
+
def get_status_color(status: WorkerStatus):
|
|
127
|
+
# set color
|
|
128
|
+
if status.value <= WorkerStatus.initializing:
|
|
129
|
+
color = 'secondary'
|
|
130
|
+
elif status.value <= WorkerStatus.launching_fem:
|
|
131
|
+
color = 'info'
|
|
132
|
+
elif status.value <= WorkerStatus.waiting:
|
|
133
|
+
color = 'success'
|
|
134
|
+
elif status.value <= WorkerStatus.running:
|
|
135
|
+
color = 'primary'
|
|
136
|
+
elif status.value <= WorkerStatus.interrupting:
|
|
137
|
+
color = 'warning'
|
|
138
|
+
elif status.value <= WorkerStatus.finished:
|
|
139
|
+
color = 'dark'
|
|
140
|
+
elif status.value <= WorkerStatus.crashed:
|
|
141
|
+
color = 'danger'
|
|
142
|
+
elif status.value <= WorkerStatus.terminated:
|
|
143
|
+
color = 'dark'
|
|
144
|
+
else:
|
|
145
|
+
color = 'danger'
|
|
146
|
+
return color
|
|
147
|
+
|
|
148
|
+
def get_df(self, equality_filters: dict = None):
|
|
149
|
+
df = self._local_data
|
|
150
|
+
|
|
151
|
+
if equality_filters is not None:
|
|
152
|
+
df = get_partial_df(df, equality_filters)
|
|
153
|
+
|
|
154
|
+
return df
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def process_monitor_main(history, status, worker_addresses, worker_names, worker_status_list, host=None, port=None, host_record=None):
|
|
158
|
+
g_application = ProcessMonitorApplication(history, status, worker_addresses, worker_names, worker_status_list)
|
|
159
|
+
|
|
160
|
+
g_home_page = HomePage(Msg.PAGE_TITLE_PROGRESS, '/', g_application)
|
|
161
|
+
g_rsm_page = PredictionModelPage(Msg.PAGE_TITLE_PREDICTION_MODEL, '/prediction-model', g_application)
|
|
162
|
+
g_optuna = OptunaVisualizerPage(Msg.PAGE_TITLE_OPTUNA_VISUALIZATION, '/optuna', g_application)
|
|
163
|
+
g_worker_page = WorkerPage(Msg.PAGE_TITLE_WORKERS, '/workers', g_application)
|
|
164
|
+
|
|
165
|
+
g_application.add_page(g_home_page, 0)
|
|
166
|
+
g_application.add_page(g_rsm_page, 1)
|
|
167
|
+
g_application.add_page(g_optuna, 2)
|
|
168
|
+
g_application.add_page(g_worker_page, 3)
|
|
169
|
+
g_application.setup_callback()
|
|
170
|
+
|
|
171
|
+
g_application.start_server(host, port, host_record)
|
|
172
|
+
|
|
173
|
+
logger.info('Monitor terminated gracefully.')
|