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.

Files changed (272) hide show
  1. pyfemtet/__init__.py +6 -1
  2. pyfemtet/_i18n/1. make_pot_and_update_po.bat +8 -0
  3. pyfemtet/_i18n/2. build_mo.bat +5 -0
  4. pyfemtet/_i18n/__init__.py +4 -0
  5. pyfemtet/_i18n/babel.cfg +2 -0
  6. pyfemtet/_i18n/i18n.py +37 -0
  7. pyfemtet/_i18n/locales/ja/LC_MESSAGES/messages.mo +0 -0
  8. pyfemtet/_i18n/locales/ja/LC_MESSAGES/messages.po +1020 -0
  9. pyfemtet/_i18n/locales/messages.pot +987 -0
  10. pyfemtet/{_message → _i18n}/messages.py +128 -41
  11. pyfemtet/_util/closing.py +19 -0
  12. pyfemtet/_util/dask_util.py +89 -7
  13. pyfemtet/_util/df_util.py +46 -0
  14. pyfemtet/_util/excel_macro_util.py +8 -3
  15. pyfemtet/_util/excel_parse_util.py +43 -23
  16. pyfemtet/_util/femtet_access_inspection.py +120 -0
  17. pyfemtet/{_femtet_config_util/autosave.py → _util/femtet_autosave.py} +7 -0
  18. pyfemtet/_util/femtet_exit.py +105 -0
  19. pyfemtet/_util/femtet_version.py +20 -0
  20. pyfemtet/_util/helper.py +103 -0
  21. pyfemtet/_util/process_util.py +107 -0
  22. pyfemtet/_util/str_enum.py +44 -0
  23. pyfemtet/core.py +15 -47
  24. pyfemtet/dispatch_extensions/__init__.py +8 -11
  25. pyfemtet/dispatch_extensions/_impl.py +42 -198
  26. pyfemtet/logger/__init__.py +8 -1
  27. pyfemtet/logger/_impl.py +5 -6
  28. pyfemtet/opt/__init__.py +3 -17
  29. pyfemtet/opt/exceptions.py +45 -0
  30. pyfemtet/opt/femopt.py +621 -0
  31. pyfemtet/opt/history/__init__.py +11 -0
  32. pyfemtet/opt/history/_history.py +1416 -0
  33. pyfemtet/opt/history/_hypervolume.py +169 -0
  34. pyfemtet/opt/history/_optimality.py +79 -0
  35. pyfemtet/opt/interface/__init__.py +17 -24
  36. pyfemtet/opt/interface/_base_interface.py +222 -0
  37. pyfemtet/opt/interface/_excel_interface/__init__.py +3 -0
  38. pyfemtet/opt/interface/_excel_interface/debug-excel-interface.xlsm +0 -0
  39. pyfemtet/opt/interface/_excel_interface/excel_interface.py +997 -0
  40. pyfemtet/opt/interface/_femtet_interface/__init__.py +3 -0
  41. pyfemtet/opt/interface/{_femtet_parametric.py → _femtet_interface/_femtet_parametric.py} +20 -12
  42. pyfemtet/opt/interface/{_femtet.py → _femtet_interface/femtet_interface.py} +508 -353
  43. pyfemtet/opt/interface/_femtet_with_nx_interface/__init__.py +5 -0
  44. pyfemtet/opt/interface/_femtet_with_nx_interface/femtet_with_nx_interface.py +230 -0
  45. pyfemtet/opt/interface/_femtet_with_nx_interface/model1.prt +0 -0
  46. pyfemtet/opt/interface/_femtet_with_nx_interface/model1.x_t +98 -0
  47. pyfemtet/opt/interface/{_femtet_with_nx → _femtet_with_nx_interface}/update_model.py +1 -3
  48. pyfemtet/opt/interface/_femtet_with_solidworks/__init__.py +5 -0
  49. pyfemtet/opt/interface/_femtet_with_solidworks/femtet_with_solidworks_interface.py +142 -0
  50. pyfemtet/opt/interface/_solidworks_interface/__init__.py +5 -0
  51. pyfemtet/opt/interface/_solidworks_interface/solidworks_interface.py +227 -0
  52. pyfemtet/opt/interface/_surrogate_model_interface/__init__.py +8 -0
  53. pyfemtet/opt/interface/_surrogate_model_interface/base_surrogate_interface.py +150 -0
  54. pyfemtet/opt/interface/_surrogate_model_interface/botorch_interface.py +298 -0
  55. pyfemtet/opt/interface/_surrogate_model_interface/debug-pof-botorch.reccsv +18 -0
  56. pyfemtet/opt/interface/_with_excel_settings/__init__.py +61 -0
  57. pyfemtet/opt/interface/_with_excel_settings/with_excel_settings.py +134 -0
  58. pyfemtet/opt/meta_script/YAML_Generator.xlsm +0 -0
  59. pyfemtet/opt/meta_script/__main__.py +58 -36
  60. pyfemtet/opt/optimizer/__init__.py +7 -9
  61. pyfemtet/opt/optimizer/_base_optimizer.py +911 -0
  62. pyfemtet/opt/optimizer/optuna_optimizer/__init__.py +9 -0
  63. pyfemtet/opt/optimizer/optuna_optimizer/_optuna_attribute.py +63 -0
  64. pyfemtet/opt/optimizer/optuna_optimizer/_optuna_optimizer.py +796 -0
  65. pyfemtet/opt/optimizer/optuna_optimizer/_pof_botorch/__init__.py +7 -0
  66. pyfemtet/opt/optimizer/optuna_optimizer/_pof_botorch/debug-pof-botorch.reccsv +18 -0
  67. pyfemtet/opt/optimizer/optuna_optimizer/_pof_botorch/enable_nonlinear_constraint.py +244 -0
  68. pyfemtet/opt/optimizer/optuna_optimizer/_pof_botorch/pof_botorch_sampler.py +1249 -0
  69. pyfemtet/opt/optimizer/optuna_optimizer/wat_ex14_parametric_jp.femprj +0 -0
  70. pyfemtet/opt/optimizer/scipy_optimizer/__init__.py +1 -0
  71. pyfemtet/opt/optimizer/scipy_optimizer/_scipy_optimizer.py +383 -0
  72. pyfemtet/opt/prediction/__init__.py +7 -0
  73. pyfemtet/opt/prediction/_botorch_utils.py +133 -0
  74. pyfemtet/opt/prediction/_gpytorch_modules_extension.py +142 -0
  75. pyfemtet/opt/prediction/_helper.py +155 -0
  76. pyfemtet/opt/prediction/_model.py +118 -0
  77. pyfemtet/opt/problem/problem.py +304 -0
  78. pyfemtet/opt/problem/variable_manager/__init__.py +20 -0
  79. pyfemtet/opt/problem/variable_manager/_string_as_expression.py +115 -0
  80. pyfemtet/opt/problem/variable_manager/_variable_manager.py +295 -0
  81. pyfemtet/opt/visualization/history_viewer/__main__.py +5 -0
  82. pyfemtet/opt/visualization/{_base.py → history_viewer/_base_application.py} +18 -13
  83. pyfemtet/opt/visualization/history_viewer/_common_pages.py +150 -0
  84. pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/alert_region.py +10 -5
  85. pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/control_femtet.py +16 -13
  86. pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/main_graph.py +117 -47
  87. pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/pm_graph.py +159 -138
  88. pyfemtet/opt/visualization/history_viewer/_process_monitor/_application.py +173 -0
  89. pyfemtet/opt/visualization/history_viewer/_process_monitor/_pages.py +291 -0
  90. pyfemtet/opt/visualization/{_wrapped_components → history_viewer/_wrapped_components}/dbc.py +1 -1
  91. pyfemtet/opt/visualization/{_wrapped_components → history_viewer/_wrapped_components}/dcc.py +1 -1
  92. pyfemtet/opt/visualization/{_wrapped_components → history_viewer/_wrapped_components}/html.py +1 -1
  93. pyfemtet/opt/visualization/history_viewer/result_viewer/__main__.py +5 -0
  94. pyfemtet/opt/visualization/{result_viewer/application.py → history_viewer/result_viewer/_application.py} +6 -6
  95. pyfemtet/opt/visualization/{result_viewer/pages.py → history_viewer/result_viewer/_pages.py} +106 -82
  96. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08.csv +18 -0
  97. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08.db +0 -0
  98. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8.jpg +0 -0
  99. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8.log +45 -0
  100. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8.pdt +0 -0
  101. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_1.jpg +0 -0
  102. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_1.pdt +0 -0
  103. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_10.jpg +0 -0
  104. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_10.pdt +0 -0
  105. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_11.jpg +0 -0
  106. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_11.pdt +0 -0
  107. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_12.jpg +0 -0
  108. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_12.pdt +0 -0
  109. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_13.jpg +0 -0
  110. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_13.pdt +0 -0
  111. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_14.jpg +0 -0
  112. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_14.pdt +0 -0
  113. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_15.jpg +0 -0
  114. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_15.pdt +0 -0
  115. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_16.jpg +0 -0
  116. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_16.pdt +0 -0
  117. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_17.jpg +0 -0
  118. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_17.pdt +0 -0
  119. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_18.jpg +0 -0
  120. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_18.pdt +0 -0
  121. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_19.jpg +0 -0
  122. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_19.pdt +0 -0
  123. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_2.jpg +0 -0
  124. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_2.pdt +0 -0
  125. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_20.jpg +0 -0
  126. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_20.pdt +0 -0
  127. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_3.jpg +0 -0
  128. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_3.pdt +0 -0
  129. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.bgr +0 -0
  130. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.bnd +0 -0
  131. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.btr +0 -0
  132. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.jpg +0 -0
  133. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.mtl +0 -0
  134. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.pdt +0 -0
  135. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.prm +0 -0
  136. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_5.jpg +0 -0
  137. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_5.pdt +0 -0
  138. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_6.jpg +0 -0
  139. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_6.pdt +0 -0
  140. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_7.jpg +0 -0
  141. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_7.pdt +0 -0
  142. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_8.jpg +0 -0
  143. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_8.pdt +0 -0
  144. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_9.jpg +0 -0
  145. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_9.pdt +0 -0
  146. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.femprj +0 -0
  147. pyfemtet/opt/visualization/plotter/main_figure_creator.py +536 -0
  148. pyfemtet/opt/visualization/plotter/pm_graph_creator.py +359 -0
  149. pyfemtet/opt/worker_status.py +120 -0
  150. {pyfemtet-0.9.6.dist-info → pyfemtet-1.0.0.dist-info}/METADATA +23 -24
  151. pyfemtet-1.0.0.dist-info/RECORD +172 -0
  152. pyfemtet-1.0.0.dist-info/entry_points.txt +3 -0
  153. pyfemtet/_femtet_config_util/exit.py +0 -59
  154. pyfemtet/_message/1. make_pot.bat +0 -11
  155. pyfemtet/_message/2. make_mo.bat +0 -6
  156. pyfemtet/_message/__init__.py +0 -5
  157. pyfemtet/_message/babel.cfg +0 -2
  158. pyfemtet/_message/locales/ja/LC_MESSAGES/messages.mo +0 -0
  159. pyfemtet/_message/locales/ja/LC_MESSAGES/messages.po +0 -570
  160. pyfemtet/_message/locales/messages.pot +0 -551
  161. pyfemtet/_warning.py +0 -87
  162. pyfemtet/brep/_impl.py +0 -18
  163. pyfemtet/opt/_femopt.py +0 -1007
  164. pyfemtet/opt/_femopt_core.py +0 -1169
  165. pyfemtet/opt/_test_utils/control_femtet.py +0 -39
  166. pyfemtet/opt/_test_utils/hyper_sphere.py +0 -24
  167. pyfemtet/opt/_test_utils/record_history.py +0 -130
  168. pyfemtet/opt/advanced_samples/excel_ui/(ref) original_project.femprj +0 -0
  169. pyfemtet/opt/advanced_samples/excel_ui/femtet-macro.xlsm +0 -0
  170. pyfemtet/opt/advanced_samples/excel_ui/pyfemtet-core.py +0 -291
  171. pyfemtet/opt/advanced_samples/excel_ui/test-pyfemtet-core.cmd +0 -22
  172. pyfemtet/opt/advanced_samples/restart/gal_ex13_parametric.femprj +0 -0
  173. pyfemtet/opt/advanced_samples/restart/gal_ex13_parametric_restart.py +0 -99
  174. pyfemtet/opt/advanced_samples/restart/gal_ex13_parametric_restart_jp.py +0 -102
  175. pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_create_training_data.py +0 -60
  176. pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_create_training_data_jp.py +0 -57
  177. pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_optimize_with_surrogate.py +0 -100
  178. pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_optimize_with_surrogate_jp.py +0 -90
  179. pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_parametric.femprj +0 -0
  180. pyfemtet/opt/interface/_base.py +0 -101
  181. pyfemtet/opt/interface/_excel_interface.py +0 -984
  182. pyfemtet/opt/interface/_femtet_excel.py +0 -141
  183. pyfemtet/opt/interface/_femtet_with_nx/__init__.py +0 -3
  184. pyfemtet/opt/interface/_femtet_with_nx/_interface.py +0 -178
  185. pyfemtet/opt/interface/_femtet_with_sldworks.py +0 -298
  186. pyfemtet/opt/interface/_surrogate/__init__.py +0 -5
  187. pyfemtet/opt/interface/_surrogate/_base.py +0 -129
  188. pyfemtet/opt/interface/_surrogate/_chaospy.py +0 -71
  189. pyfemtet/opt/interface/_surrogate/_singletaskgp.py +0 -71
  190. pyfemtet/opt/interface/_surrogate_excel.py +0 -102
  191. pyfemtet/opt/optimizer/_base.py +0 -376
  192. pyfemtet/opt/optimizer/_optuna/_botorch_patch/enable_nonlinear_constraint.py +0 -220
  193. pyfemtet/opt/optimizer/_optuna/_optuna.py +0 -434
  194. pyfemtet/opt/optimizer/_optuna/_pof_botorch.py +0 -1914
  195. pyfemtet/opt/optimizer/_scipy.py +0 -159
  196. pyfemtet/opt/optimizer/_scipy_scalar.py +0 -127
  197. pyfemtet/opt/optimizer/parameter.py +0 -113
  198. pyfemtet/opt/prediction/_base.py +0 -61
  199. pyfemtet/opt/prediction/single_task_gp.py +0 -119
  200. pyfemtet/opt/samples/femprj_sample/ParametricIF.femprj +0 -0
  201. pyfemtet/opt/samples/femprj_sample/ParametricIF.py +0 -29
  202. pyfemtet/opt/samples/femprj_sample/ParametricIF_test_result.reccsv +0 -13
  203. pyfemtet/opt/samples/femprj_sample/cad_ex01_NX.femprj +0 -0
  204. pyfemtet/opt/samples/femprj_sample/cad_ex01_NX.prt +0 -0
  205. pyfemtet/opt/samples/femprj_sample/cad_ex01_NX.py +0 -135
  206. pyfemtet/opt/samples/femprj_sample/cad_ex01_NX_test_result.reccsv +0 -23
  207. pyfemtet/opt/samples/femprj_sample/cad_ex01_SW.SLDPRT +0 -0
  208. pyfemtet/opt/samples/femprj_sample/cad_ex01_SW.femprj +0 -0
  209. pyfemtet/opt/samples/femprj_sample/cad_ex01_SW.py +0 -131
  210. pyfemtet/opt/samples/femprj_sample/cad_ex01_SW_test_result.reccsv +0 -23
  211. pyfemtet/opt/samples/femprj_sample/constrained_pipe.femprj +0 -0
  212. pyfemtet/opt/samples/femprj_sample/constrained_pipe.py +0 -96
  213. pyfemtet/opt/samples/femprj_sample/constrained_pipe_test_result.reccsv +0 -13
  214. pyfemtet/opt/samples/femprj_sample/gal_ex58_parametric.femprj +0 -0
  215. pyfemtet/opt/samples/femprj_sample/gal_ex58_parametric.py +0 -74
  216. pyfemtet/opt/samples/femprj_sample/gal_ex58_parametric_test_result.reccsv +0 -13
  217. pyfemtet/opt/samples/femprj_sample/gau_ex08_parametric.femprj +0 -0
  218. pyfemtet/opt/samples/femprj_sample/gau_ex08_parametric.py +0 -58
  219. pyfemtet/opt/samples/femprj_sample/gau_ex08_parametric_test_result.reccsv +0 -23
  220. pyfemtet/opt/samples/femprj_sample/gau_ex12_parametric.femprj +0 -0
  221. pyfemtet/opt/samples/femprj_sample/gau_ex12_parametric.py +0 -52
  222. pyfemtet/opt/samples/femprj_sample/her_ex40_parametric.femprj +0 -0
  223. pyfemtet/opt/samples/femprj_sample/her_ex40_parametric.py +0 -138
  224. pyfemtet/opt/samples/femprj_sample/her_ex40_parametric_test_result.reccsv +0 -18
  225. pyfemtet/opt/samples/femprj_sample/paswat_ex1_parametric.femprj +0 -0
  226. pyfemtet/opt/samples/femprj_sample/paswat_ex1_parametric.py +0 -60
  227. pyfemtet/opt/samples/femprj_sample/paswat_ex1_parametric_parallel.py +0 -61
  228. pyfemtet/opt/samples/femprj_sample/paswat_ex1_parametric_test_result.reccsv +0 -18
  229. pyfemtet/opt/samples/femprj_sample/wat_ex14_parametric.femprj +0 -0
  230. pyfemtet/opt/samples/femprj_sample/wat_ex14_parametric.py +0 -58
  231. pyfemtet/opt/samples/femprj_sample/wat_ex14_parametric_parallel.py +0 -58
  232. pyfemtet/opt/samples/femprj_sample/wat_ex14_parametric_test_result.reccsv +0 -18
  233. pyfemtet/opt/samples/femprj_sample_jp/ParametricIF_jp.femprj +0 -0
  234. pyfemtet/opt/samples/femprj_sample_jp/ParametricIF_jp.py +0 -29
  235. pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_NX_jp.femprj +0 -0
  236. pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_NX_jp.py +0 -129
  237. pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_SW_jp.femprj +0 -0
  238. pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_SW_jp.py +0 -125
  239. pyfemtet/opt/samples/femprj_sample_jp/constrained_pipe_jp.py +0 -93
  240. pyfemtet/opt/samples/femprj_sample_jp/gal_ex58_parametric_jp.femprj +0 -0
  241. pyfemtet/opt/samples/femprj_sample_jp/gal_ex58_parametric_jp.py +0 -70
  242. pyfemtet/opt/samples/femprj_sample_jp/gau_ex08_parametric_jp.femprj +0 -0
  243. pyfemtet/opt/samples/femprj_sample_jp/gau_ex08_parametric_jp.py +0 -57
  244. pyfemtet/opt/samples/femprj_sample_jp/gau_ex12_parametric_jp.py +0 -52
  245. pyfemtet/opt/samples/femprj_sample_jp/her_ex40_parametric_jp.femprj +0 -0
  246. pyfemtet/opt/samples/femprj_sample_jp/her_ex40_parametric_jp.py +0 -138
  247. pyfemtet/opt/samples/femprj_sample_jp/paswat_ex1_parametric_jp.femprj +0 -0
  248. pyfemtet/opt/samples/femprj_sample_jp/paswat_ex1_parametric_jp.py +0 -58
  249. pyfemtet/opt/samples/femprj_sample_jp/paswat_ex1_parametric_parallel_jp.py +0 -59
  250. pyfemtet/opt/samples/femprj_sample_jp/wat_ex14_parametric_jp.py +0 -56
  251. pyfemtet/opt/samples/femprj_sample_jp/wat_ex14_parametric_parallel_jp.py +0 -56
  252. pyfemtet/opt/visualization/_complex_components/main_figure_creator.py +0 -332
  253. pyfemtet/opt/visualization/_complex_components/pm_graph_creator.py +0 -201
  254. pyfemtet/opt/visualization/_process_monitor/application.py +0 -226
  255. pyfemtet/opt/visualization/_process_monitor/pages.py +0 -406
  256. pyfemtet/opt/visualization/_wrapped_components/__init__.py +0 -0
  257. pyfemtet/opt/visualization/result_viewer/__init__.py +0 -0
  258. pyfemtet-0.9.6.dist-info/RECORD +0 -158
  259. pyfemtet-0.9.6.dist-info/entry_points.txt +0 -3
  260. /pyfemtet/{_femtet_config_util → opt/problem}/__init__.py +0 -0
  261. /pyfemtet/{brep → opt/visualization/history_viewer}/__init__.py +0 -0
  262. /pyfemtet/opt/{_test_utils → visualization/history_viewer/_complex_components}/__init__.py +0 -0
  263. /pyfemtet/opt/{optimizer/_optuna → visualization/history_viewer/_process_monitor}/__init__.py +0 -0
  264. /pyfemtet/opt/{optimizer/_optuna/_botorch_patch → visualization/history_viewer/_wrapped_components}/__init__.py +0 -0
  265. /pyfemtet/opt/visualization/{_wrapped_components → history_viewer/_wrapped_components}/str_enum.py +0 -0
  266. /pyfemtet/opt/visualization/{result_viewer → history_viewer/result_viewer}/.gitignore +0 -0
  267. /pyfemtet/opt/visualization/{_complex_components → history_viewer/result_viewer}/__init__.py +0 -0
  268. /pyfemtet/opt/visualization/{_process_monitor → plotter}/__init__.py +0 -0
  269. /pyfemtet/opt/{samples/femprj_sample_jp/wat_ex14_parametric_jp.femprj → wat_ex14_parametric_jp.femprj} +0 -0
  270. {pyfemtet-0.9.6.dist-info → pyfemtet-1.0.0.dist-info}/LICENSE +0 -0
  271. {pyfemtet-0.9.6.dist-info → pyfemtet-1.0.0.dist-info}/LICENSE_THIRD_PARTY.txt +0 -0
  272. {pyfemtet-0.9.6.dist-info → pyfemtet-1.0.0.dist-info}/WHEEL +0 -0
@@ -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 dash import dash_table
10
- from pyfemtet.opt.visualization._wrapped_components import html, dcc, dbc
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.visualization._complex_components.pm_graph_creator import PredictionModelCreator
25
- from pyfemtet.opt.visualization._base import AbstractPage, logger
26
- from pyfemtet._message import Msg
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.rsm_creator: PredictionModelCreator = PredictionModelCreator()
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], color='success')
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, Msg.LABEL_OF_REDRAW_PREDICTION_MODEL_GRAPH_BUTTON])
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([dbc.Col(html.Span(Msg.LABEL_OF_AXIS1_SELECTION), align='center', style={'text-align': 'end'}, width=2), dbc.Col(self.axis_controllers[0])]),
154
- dbc.Row([dbc.Col(html.Span(Msg.LABEL_OF_AXIS2_SELECTION), align='center', style={'text-align': 'end'}, width=2), dbc.Col(self.axis_controllers[1])], id='prm-axis-2-dropdown'),
155
- dbc.Row([dbc.Col(html.Span(Msg.LABEL_OF_AXIS3_SELECTION), align='center', style={'text-align': 'end'}, width=2), dbc.Col(self.axis_controllers[2])]),
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(): state1.pop('display')
221
- if 'display' in state2.keys(): state2.pop('display')
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 history
257
- if len(self.data_accessor()) == 0:
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
- self.rsm_creator.fit(
290
+ model = SingleTaskGPModel()
291
+ self.pyfemtet_model.update_model(model)
292
+ self.pyfemtet_model.fit(
262
293
  self.application.history,
263
- self.data_accessor(),
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
- # Output(self.data_length.id, self.data_length_prop), # To determine whether Process Monitor should update the graph, the main graph remembers the current amount of data.
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(command, active_tab_id, axis1_label, axis2_label, axis3_label, _2, prm_values, is_3d):
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.data_accessor()) == 0:
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.rsm_creator, 'history'):
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
- if not is_3d:
309
- axis2_label = None
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
- # get indices to remove
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
- # replace values to remove to None
316
- if idx1 is not None:
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
- # remove all None from array: prm_values is now remaining_x
322
- while None in prm_values:
323
- prm_values.remove(None)
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
- # create figure
326
- fig = self.rsm_creator.create_figure(
327
- axis1_label,
328
- axis3_label,
329
- remaining_x=prm_values,
330
- prm_name_2=axis2_label,
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
- # get ub and lb
408
- lb_column = prm_name + '_lower_bound'
409
- ub_column = prm_name + '_upper_bound'
410
- # get minimum lb and maximum ub
411
- df = self.data_accessor()
412
- lb = df[lb_column].min()
413
- ub = df[ub_column].max()
414
- # if lb or ub is not specified, use value instead
415
- lb = df[prm_name].min() if np.isnan(lb) else lb
416
- ub = df[prm_name].max() if np.isnan(ub) else ub
417
- # create slider
418
- value = (lb + ub) / 2
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
- dcc.Slider(
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] for style in current_styles],
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.')