pyfemtet 0.9.5__py3-none-any.whl → 1.0.0b0__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 +29 -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 +94 -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 +608 -0
- pyfemtet/opt/history/__init__.py +11 -0
- pyfemtet/opt/history/_history.py +1404 -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 +999 -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} +505 -349
- 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 +122 -0
- pyfemtet/opt/interface/_solidworks_interface/__init__.py +5 -0
- pyfemtet/opt/interface/_solidworks_interface/solidworks_interface.py +206 -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 +885 -0
- pyfemtet/opt/optimizer/optuna_optimizer/__init__.py +9 -0
- pyfemtet/opt/optimizer/optuna_optimizer/_optuna_attribute.py +73 -0
- pyfemtet/opt/optimizer/optuna_optimizer/_optuna_optimizer.py +678 -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 +364 -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.5.dist-info → pyfemtet-1.0.0b0.dist-info}/METADATA +23 -24
- pyfemtet-1.0.0b0.dist-info/RECORD +172 -0
- pyfemtet-1.0.0b0.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.5.dist-info/RECORD +0 -158
- pyfemtet-0.9.5.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.5.dist-info → pyfemtet-1.0.0b0.dist-info}/LICENSE +0 -0
- {pyfemtet-0.9.5.dist-info → pyfemtet-1.0.0b0.dist-info}/LICENSE_THIRD_PARTY.txt +0 -0
- {pyfemtet-0.9.5.dist-info → pyfemtet-1.0.0b0.dist-info}/WHEEL +0 -0
|
@@ -1,38 +1,41 @@
|
|
|
1
|
-
import
|
|
2
|
-
import locale
|
|
3
|
-
from dataclasses import dataclass
|
|
1
|
+
from .i18n import _
|
|
4
2
|
|
|
5
|
-
loc, encoding = locale.getlocale()
|
|
6
3
|
|
|
7
|
-
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
else:
|
|
12
|
-
# get translation
|
|
13
|
-
if 'japanese' in loc.lower():
|
|
14
|
-
from babel.support import Translations
|
|
4
|
+
class Message:
|
|
5
|
+
# rule
|
|
6
|
+
TEST = _('Hello!')
|
|
15
7
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
_ = translations.gettext
|
|
8
|
+
# ===== common =====
|
|
9
|
+
ENTER_TO_QUIT = _('Press enter to quit...')
|
|
10
|
+
CONSTRAINT = _('constraint')
|
|
11
|
+
HIDDEN_CONSTRAINT = _('hidden constraint')
|
|
21
12
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
13
|
+
# ===== pyfemtet.dispatch_extensions =====
|
|
14
|
+
WAIT_FOR_LAUNCH_FEMTET = _('Waiting for launch femtet...')
|
|
15
|
+
TRY_TO_CONNECT_FEMTET = _('Trying to connect Femtet...')
|
|
25
16
|
|
|
17
|
+
@staticmethod
|
|
18
|
+
def F_FEMTET_CONNECTED(pid):
|
|
19
|
+
return _(
|
|
20
|
+
'Successfully connected. The pid of Femtet is {pid}.',
|
|
21
|
+
pid=pid
|
|
22
|
+
)
|
|
26
23
|
|
|
27
|
-
@
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
@staticmethod
|
|
25
|
+
def F_SEARCHING_FEMTET_WITH_SPECIFIC_PID(pid):
|
|
26
|
+
return _(
|
|
27
|
+
'Searching Femtet (pid = {pid}) ...',
|
|
28
|
+
pid=pid
|
|
29
|
+
)
|
|
33
30
|
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
@staticmethod
|
|
32
|
+
def F_ERR_FEMTET_CONNECTION_TIMEOUT(pid, timeout):
|
|
33
|
+
return _(
|
|
34
|
+
'Connection to Femtet (pid = {pid}) was not'
|
|
35
|
+
'established in {timeout} sec',
|
|
36
|
+
pid=pid,
|
|
37
|
+
timeout=timeout,
|
|
38
|
+
)
|
|
36
39
|
|
|
37
40
|
# ===== pyfemtet.opt femopt core =====
|
|
38
41
|
ERR_CHECK_MINMAX = _('The magnitude relationship is incorrect.')
|
|
@@ -42,13 +45,12 @@ class Message:
|
|
|
42
45
|
|
|
43
46
|
# ===== pyfemtet.opt FEMOpt =====
|
|
44
47
|
ERR_NO_INITIAL_VALUE = _('Please specify initial_value.')
|
|
45
|
-
ERR_CONTAIN_GOGH_ACCESS_IN_STRICT_CONSTRAINT = _(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
'otherwise history data will be lost.')
|
|
48
|
+
ERR_CONTAIN_GOGH_ACCESS_IN_STRICT_CONSTRAINT = _(
|
|
49
|
+
'Constraint functions are evaluated before analysis is performed, '
|
|
50
|
+
'so do not access Femtet.Gogh. If you want your '
|
|
51
|
+
'constraints to include values after analysis is performed, set '
|
|
52
|
+
'the `strict` argument to False.')
|
|
53
|
+
|
|
52
54
|
OPTIMIZATION_FINISHED = _('Optimization finished. Results were saved in following:')
|
|
53
55
|
ERR_NO_BOUNDS = _('No bounds specified.')
|
|
54
56
|
CONFIRM_BEFORE_EXIT = _('The optimization is now complete. You can view the results on the monitor until you press Enter to exit the program.')
|
|
@@ -59,8 +61,25 @@ class Message:
|
|
|
59
61
|
ERR_MODEL_UPDATE_FAILED = _('Model update failed.')
|
|
60
62
|
ERR_NO_MAKEPY = _('It was detected that the configuration of Femtet python macro constants has not been completed. The configuration was done automatically (python -m win32com.client.makepy FemtetMacro). Please restart the program. If the error persists, please run "py -m win32com.client.makepy FemtetMacro" or "python -m win32com.client.makepy FemtetMacro" on the command prompt.')
|
|
61
63
|
ERR_FEMTET_CONNECTION_FAILED = _('Failed to connect to Femtet.')
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
|
|
65
|
+
@staticmethod
|
|
66
|
+
def F_ERR_FEMTET_CRASHED_AND_RESTART_FAILED(name):
|
|
67
|
+
return _(
|
|
68
|
+
'The Femtet process crashed and '
|
|
69
|
+
'Python failed to restore Femtet. '
|
|
70
|
+
'API: {name}',
|
|
71
|
+
name=name
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
@staticmethod
|
|
75
|
+
def F_WARN_FEMTET_CRASHED_AND_TRY_RESTART(name):
|
|
76
|
+
return _(
|
|
77
|
+
'An abnormal termination of the Femtet '
|
|
78
|
+
'process has been detected. Recovery will '
|
|
79
|
+
'be attempted. API: {name}',
|
|
80
|
+
name=name,
|
|
81
|
+
)
|
|
82
|
+
|
|
64
83
|
INFO_FEMTET_CRASHED_AND_RESTARTED = _('Femtet has been restarted and will perform analysis and attempt to recover.')
|
|
65
84
|
ERR_NEW_FEMTET_BUT_NO_FEMPRJ = _("If you specify 'new' as the 'connect_method' argument, set the 'femprj_path' argument to existing femprj file path.")
|
|
66
85
|
ERR_NO_SUCH_PARAMETER_IN_FEMTET = _('The specified variable is not included in the Femtet analysis model. Note the capitalization of the variable.')
|
|
@@ -75,7 +94,7 @@ class Message:
|
|
|
75
94
|
ERR_MODEL_MESH_FAILED = _('Mesh generation failed')
|
|
76
95
|
ERR_PARAMETRIC_SOLVE_FAILED = _('Parametric solve failed')
|
|
77
96
|
ERR_SOLVE_FAILED = _('Solve failed.')
|
|
78
|
-
ERR_OPEN_RESULT_FAILED = _('
|
|
97
|
+
ERR_OPEN_RESULT_FAILED = _('Failed to open result.')
|
|
79
98
|
ERR_CLOSE_FEMTET_FAILED = _('Failed to close Femtet.')
|
|
80
99
|
ERR_FAILED_TO_SAVE_PDT = _('Failed to save result (.pdt) file.')
|
|
81
100
|
ERR_FAILED_TO_SAVE_JPG = _('Failed to save screenshot (.jpg).')
|
|
@@ -100,6 +119,77 @@ class Message:
|
|
|
100
119
|
START_CANDIDATE_WITH_PARAMETER_CONSTRAINT = _('Start to candidate new parameter set with constraints. This process may take a long time.')
|
|
101
120
|
WARN_UPDATE_FEM_PARAMETER_TOOK_A_LONG_TIME = _('Updating FEM parameter during evaluating constraints take a long time. Please consider not to use FEM variables in constraint functions and set `update_fem` to False.')
|
|
102
121
|
|
|
122
|
+
# ===== optuna optimizer =====
|
|
123
|
+
@staticmethod
|
|
124
|
+
def F_WARN_INVALID_ARG_FOR_SAMPLER(key, sampler_name):
|
|
125
|
+
return _(
|
|
126
|
+
'The given argument {key} is not '
|
|
127
|
+
'included in ones of {sampler_name}. '
|
|
128
|
+
'{key} is ignored.',
|
|
129
|
+
key=key, sampler_name=sampler_name,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
# ===== scipy optimizer =====
|
|
133
|
+
WARN_SCIPY_NELDER_MEAD_BOUND = _(
|
|
134
|
+
'Sometimes Nelder-Mead cannot start optimization '
|
|
135
|
+
'with the initial condition what is same with '
|
|
136
|
+
'lower bounds or upper bounds.'
|
|
137
|
+
)
|
|
138
|
+
ERR_SCIPY_NOT_IMPLEMENT_CATEGORICAL = _(
|
|
139
|
+
'Cannot use categorical parameter with ScipyOptimizer'
|
|
140
|
+
)
|
|
141
|
+
ERR_SCIPY_HARD_CONSTRAINT_VIOLATION = _(
|
|
142
|
+
en_message='Hard constraint violation! scipy cannot continue '
|
|
143
|
+
'optimization. Only `SLSQP` supports optimization '
|
|
144
|
+
'with hard constraint optimization problem. '
|
|
145
|
+
'If you see this message even if you are using it, '
|
|
146
|
+
'please try to following:\n'
|
|
147
|
+
'- Use small `eps` by `options` argument.\n'
|
|
148
|
+
'- Set `constraint_enhancement`to the value that '
|
|
149
|
+
'it larger than the variation of the constraint '
|
|
150
|
+
'function when input variables within the range '
|
|
151
|
+
'of `eps`.',
|
|
152
|
+
jp_message='hard constraint を扱うには'
|
|
153
|
+
'method に SLSQP を使用してください。'
|
|
154
|
+
'SLSQP を使用しているのにこのメッセージが表示される場合、\n'
|
|
155
|
+
'- options から eps を小さくするか、'
|
|
156
|
+
'- eps の値の範囲内で x が変動したときの'
|
|
157
|
+
'拘束関数の変動量を上回るように'
|
|
158
|
+
'constraint_enhancement を大きく\n'
|
|
159
|
+
'してみてください。',
|
|
160
|
+
)
|
|
161
|
+
ERR_SCIPY_HIDDEN_CONSTRAINT = _(
|
|
162
|
+
en_message='ScipyOptimizer cannot continue optimization '
|
|
163
|
+
'when encountered the input variables that '
|
|
164
|
+
'break FEM model.',
|
|
165
|
+
jp_message='ScipyOptimizer では解析ができない'
|
|
166
|
+
'設計変数の組合せをスキップできません。'
|
|
167
|
+
)
|
|
168
|
+
ERR_SCIPY_NOT_IMPLEMENT_SKIP = _('ScipyOptimizer cannot skip solve.')
|
|
169
|
+
|
|
170
|
+
@staticmethod
|
|
171
|
+
def F_ERR_SCIPY_METHOD_NOT_IMPLEMENT_HARD_CONSTRAINT(method):
|
|
172
|
+
return _('{method} cannot handle hard constraint.', method=method)
|
|
173
|
+
|
|
174
|
+
WARN_SCIPY_SLSQP_CANNOT_PROCESS_SOFT_CONSTRAINT = _(
|
|
175
|
+
'SLSQP cannot handle soft constraint. '
|
|
176
|
+
'The constraint is handled as a hard one.'
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
# ===== PoFBoTorchSampler =====
|
|
180
|
+
WARN_USING_FEM_IN_NLC = _(
|
|
181
|
+
'Accessing FEM API inside hard constraint '
|
|
182
|
+
'function may be very slow.')
|
|
183
|
+
WARN_NO_FEASIBLE_BATCH_INITIAL_CONDITION = _(
|
|
184
|
+
'gen_batch_initial_conditions() failed to generate '
|
|
185
|
+
'feasible initial conditions for acquisition '
|
|
186
|
+
'function optimization sub-problem, '
|
|
187
|
+
'so trying to use random feasible parameters '
|
|
188
|
+
'as initial conditions.'
|
|
189
|
+
'The constraint functions or solutions spaces '
|
|
190
|
+
'may be too complicated.'
|
|
191
|
+
)
|
|
192
|
+
|
|
103
193
|
# ===== pyfemtet.opt.visualization =====
|
|
104
194
|
# control_femtet.py
|
|
105
195
|
LABEL_CONNECT_FEMTET_BUTTON = _('Connect to Femtet')
|
|
@@ -166,9 +256,6 @@ class Message:
|
|
|
166
256
|
'the `save_pdt` argument of FemtetInterface in optimization script'
|
|
167
257
|
'(default to `all`).')
|
|
168
258
|
ERR_FAILED_TO_OPEN_PREFIX = _('Failed to open ')
|
|
169
|
-
ERR_NO_SUCH_MODEL_IN_FEMPRJ = _('Specified model is not in current project. '
|
|
170
|
-
'Please check opened project. '
|
|
171
|
-
'For example, not "analysis model only" but your .femprj file.')
|
|
172
259
|
WARN_INCONSISTENT_FEMPRJ_PATH = _('.femprj file path of the history csv is invalid. Please certify matching between csv and opening .femprj file.')
|
|
173
260
|
WARN_INVALID_MODEL_NAME = _('Analysis model name of the history csv is invalid. Please certify matching between csv and opening analysis model.')
|
|
174
261
|
WARN_INCONSISTENT_MODEL_NAME = _('Analysis model name of the history csv and opened in Femtet is inconsistent. Please certify matching between csv and opening analysis model.')
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from traceback import print_tb
|
|
3
|
+
|
|
4
|
+
__all__ = ['closing']
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class closing:
|
|
8
|
+
def __init__(self, thing):
|
|
9
|
+
self.thing = thing
|
|
10
|
+
|
|
11
|
+
def __enter__(self):
|
|
12
|
+
return self.thing
|
|
13
|
+
|
|
14
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
15
|
+
if exc_type is not None:
|
|
16
|
+
print(f'===== An exception is raised. Try to close resource. ===== ', file=sys.stderr)
|
|
17
|
+
print_tb(exc_tb)
|
|
18
|
+
print(f'{exc_type.__name__}: {exc_val}', file=sys.stderr)
|
|
19
|
+
self.thing.close()
|
pyfemtet/_util/dask_util.py
CHANGED
|
@@ -1,10 +1,92 @@
|
|
|
1
|
-
|
|
2
|
-
from
|
|
1
|
+
import warnings
|
|
2
|
+
from packaging.version import Version
|
|
3
|
+
from threading import Lock as _ThreadingLock
|
|
3
4
|
|
|
5
|
+
import dask
|
|
6
|
+
from dask.distributed import LocalCluster, Client, Lock as _DaskLock, Nanny
|
|
7
|
+
from dask.distributed import get_client as _get_client, get_worker as _get_worker
|
|
8
|
+
from dask import config as cfg
|
|
9
|
+
|
|
10
|
+
from pyfemtet.logger import get_dask_logger, remove_all_output, get_module_logger
|
|
11
|
+
|
|
12
|
+
if Version(dask.__version__) < Version('2024.12.1'):
|
|
13
|
+
import pyfemtet
|
|
14
|
+
raise RuntimeError(
|
|
15
|
+
f'pyfemtet {pyfemtet.__version__} requires dask >= 2024.12.1, '
|
|
16
|
+
f'but the existing dask == {dask.__version__}. '
|
|
17
|
+
f'Please consider to update dask.\n'
|
|
18
|
+
f'ex: `py -m pip install dask distributed`'
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
remove_all_output(get_dask_logger())
|
|
22
|
+
|
|
23
|
+
warnings.filterwarnings('ignore', category=RuntimeWarning, message="Couldn't detect a suitable IP address")
|
|
24
|
+
|
|
25
|
+
cfg.set({'distributed.scheduler.worker-ttl': None})
|
|
26
|
+
|
|
27
|
+
logger = get_module_logger('opt.dask', False)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
__all__ = [
|
|
31
|
+
'get_client',
|
|
32
|
+
'get_worker',
|
|
33
|
+
'Lock',
|
|
34
|
+
'LocalCluster',
|
|
35
|
+
'Client',
|
|
36
|
+
'Nanny',
|
|
37
|
+
'DummyClient',
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
_lock_pool = {}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def get_client():
|
|
44
|
+
try:
|
|
45
|
+
return _get_client()
|
|
46
|
+
except ValueError:
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def get_worker():
|
|
51
|
+
try:
|
|
52
|
+
return _get_worker()
|
|
53
|
+
except ValueError:
|
|
54
|
+
return None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def Lock(name, client=None):
|
|
58
|
+
global _lock_pool
|
|
59
|
+
|
|
60
|
+
if client is None:
|
|
61
|
+
client = get_client()
|
|
62
|
+
|
|
63
|
+
if client is not None:
|
|
64
|
+
# import inspect
|
|
65
|
+
# logger.debug(f'{name}, {[stack.function for stack in inspect.stack()[1:]]}')
|
|
66
|
+
with cfg.set({"distributed.scheduler.locks.lease-timeout": "inf"}):
|
|
67
|
+
_lock = _DaskLock(name)
|
|
4
68
|
|
|
5
|
-
def lock_or_no_lock(name: str, client=None):
|
|
6
|
-
lock = Lock(name, client)
|
|
7
|
-
if lock.client is None:
|
|
8
|
-
return nullcontext()
|
|
9
69
|
else:
|
|
10
|
-
|
|
70
|
+
if name in _lock_pool:
|
|
71
|
+
_lock = _lock_pool[name]
|
|
72
|
+
else:
|
|
73
|
+
_lock = _ThreadingLock()
|
|
74
|
+
_lock_pool.update({name: _lock})
|
|
75
|
+
|
|
76
|
+
return _lock
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class DummyClient:
|
|
80
|
+
|
|
81
|
+
@staticmethod
|
|
82
|
+
def scheduler_info():
|
|
83
|
+
return dict(workers=dict())
|
|
84
|
+
|
|
85
|
+
def __enter__(self):
|
|
86
|
+
return self
|
|
87
|
+
|
|
88
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
89
|
+
pass
|
|
90
|
+
|
|
91
|
+
def map(self, *args, **kwargs): ...
|
|
92
|
+
def gather(self, *args, **kwargs): ...
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
__all__ = [
|
|
5
|
+
'apply_partial_df',
|
|
6
|
+
'get_partial_df',
|
|
7
|
+
]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_index(df, equality_filters):
|
|
11
|
+
# フィルタ条件に一致する行のインデックスを取得
|
|
12
|
+
# noinspection PyUnresolvedReferences
|
|
13
|
+
return (df[list(equality_filters.keys())] == pd.Series(equality_filters)).all(axis=1)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_partial_df(df: pd.DataFrame, equality_filters: dict):
|
|
17
|
+
return df[get_index(df, equality_filters)]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def apply_partial_df(df: pd.DataFrame, partial_df: pd.DataFrame, equality_filters: dict):
|
|
21
|
+
|
|
22
|
+
idx = get_index(df, equality_filters)
|
|
23
|
+
|
|
24
|
+
# インデクスに対応する部分を上書き
|
|
25
|
+
assert len(df[idx]) == len(partial_df), ('equality_filters の実行結果と'
|
|
26
|
+
'与えられた partial_df の長さが一致しません。')
|
|
27
|
+
df[idx] = partial_df
|
|
28
|
+
|
|
29
|
+
return df
|
|
@@ -9,7 +9,13 @@ import win32process
|
|
|
9
9
|
|
|
10
10
|
from pyfemtet.logger import get_module_logger
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
'watch_excel_macro_error'
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
logger = get_module_logger('util.excel', False)
|
|
13
19
|
|
|
14
20
|
|
|
15
21
|
def _get_pid(hwnd):
|
|
@@ -152,7 +158,6 @@ def watch_excel_macro_error(excel_, timeout, restore_book=True):
|
|
|
152
158
|
return _ExcelDialogProcessor(excel_, timeout, restore_book)
|
|
153
159
|
|
|
154
160
|
|
|
155
|
-
|
|
156
161
|
if __name__ == '__main__':
|
|
157
162
|
|
|
158
163
|
import os
|
|
@@ -161,8 +166,8 @@ if __name__ == '__main__':
|
|
|
161
166
|
path = os.path.abspath('sample.xlsm')
|
|
162
167
|
path2 = os.path.abspath('sample2.xlsm')
|
|
163
168
|
|
|
164
|
-
|
|
165
169
|
from win32com.client import Dispatch
|
|
170
|
+
# noinspection PyUnresolvedReferences
|
|
166
171
|
from pythoncom import com_error
|
|
167
172
|
|
|
168
173
|
logger.debug('Excel を起動しています。')
|
|
@@ -2,8 +2,11 @@ import os
|
|
|
2
2
|
import numpy as np
|
|
3
3
|
import pandas as pd
|
|
4
4
|
|
|
5
|
+
from pyfemtet.opt.history._history import ColumnManager # to use _reconvert
|
|
6
|
+
|
|
5
7
|
|
|
6
8
|
__all__ = [
|
|
9
|
+
'_EMPTY_CHOICE',
|
|
7
10
|
'ParseAsParameter',
|
|
8
11
|
'ParseAsConstraint',
|
|
9
12
|
'ParseAsObjective',
|
|
@@ -13,15 +16,18 @@ __all__ = [
|
|
|
13
16
|
]
|
|
14
17
|
|
|
15
18
|
|
|
16
|
-
|
|
19
|
+
_EMPTY_CHOICE = ''
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def parse_excel(book_path, sheet_name, keyword, required, optional, raise_if_no_keyword) -> pd.DataFrame:
|
|
17
23
|
"""Excel シートからパラメータを取得します。
|
|
18
24
|
|
|
19
25
|
シートのパースプロセスは以下の通りです。
|
|
20
26
|
|
|
21
27
|
1. シート全体 (A1 セルから、値が入力されている最終セルまで) をデータに取り込みます。
|
|
22
|
-
2.
|
|
23
|
-
3.
|
|
24
|
-
4.
|
|
28
|
+
2. すべてのセルが空白である列をデータから除きます。
|
|
29
|
+
3. すべてのセルが空白である行をデータから除きます。
|
|
30
|
+
4. 最も左上(上が優先)にある keyword に一致するセルより上および左の行・列をデータから除きます。
|
|
25
31
|
|
|
26
32
|
Args:
|
|
27
33
|
book_path: Excel book のパス。
|
|
@@ -29,7 +35,7 @@ def parse_excel(book_path, sheet_name, keyword, required, optional, raise_if_no_
|
|
|
29
35
|
keyword (str): 必ず含まれるべき、表データの最初の列名として使う文字列。
|
|
30
36
|
required (list[str]): 必ず含まれるべき、表データの列名として使う文字列のリスト。
|
|
31
37
|
optional (list[str]): 表データの列名として使ってよい文字列のリスト。
|
|
32
|
-
raise_if_no_keyword (bool
|
|
38
|
+
raise_if_no_keyword (bool): キーワードがなかった場合エラーとするか。
|
|
33
39
|
|
|
34
40
|
Returns:
|
|
35
41
|
|
|
@@ -55,6 +61,7 @@ def parse_excel(book_path, sheet_name, keyword, required, optional, raise_if_no_
|
|
|
55
61
|
df = pd.DataFrame(df.iloc[1+r:, c:].values, columns=df.iloc[r, c:].values)
|
|
56
62
|
|
|
57
63
|
# NaN のみからなる行を最初に見つけるまでデータに追加する
|
|
64
|
+
# <=> 表の下限を決める
|
|
58
65
|
valid_rows = []
|
|
59
66
|
for row in df.index:
|
|
60
67
|
if df.loc[row].notna().sum():
|
|
@@ -63,10 +70,36 @@ def parse_excel(book_path, sheet_name, keyword, required, optional, raise_if_no_
|
|
|
63
70
|
break
|
|
64
71
|
df = df.loc[valid_rows]
|
|
65
72
|
|
|
66
|
-
# NaN のみからなる列を削除する
|
|
73
|
+
# NaN のみからなる列を削除する <=> 表の右限を決める
|
|
67
74
|
valid_columns = [col for i, col in enumerate(df.columns) if df.iloc[:, i].notna().sum()]
|
|
68
75
|
df = df[valid_columns]
|
|
69
76
|
|
|
77
|
+
# choices は list に変換する
|
|
78
|
+
key = ParseAsParameter.choices
|
|
79
|
+
if key in df.columns:
|
|
80
|
+
if key in df.columns:
|
|
81
|
+
choices = []
|
|
82
|
+
for v in df[key]:
|
|
83
|
+
v = str(v)
|
|
84
|
+
if v == 'nan':
|
|
85
|
+
choices.append('[]') # _reconvert_objects の中で SyntaxError になるため。後で置換する。
|
|
86
|
+
else:
|
|
87
|
+
if not v.startswith('['):
|
|
88
|
+
v = f'[{v}'
|
|
89
|
+
if not v.endswith(']'):
|
|
90
|
+
v = f'{v}]'
|
|
91
|
+
choices.append(v)
|
|
92
|
+
|
|
93
|
+
df[key] = choices
|
|
94
|
+
|
|
95
|
+
dummy_meta_columns = ['prm.cat.choices' if (column == key)
|
|
96
|
+
else ''
|
|
97
|
+
for column in df.columns]
|
|
98
|
+
|
|
99
|
+
ColumnManager._reconvert_objects(df, dummy_meta_columns)
|
|
100
|
+
|
|
101
|
+
df[key] = [_EMPTY_CHOICE if len(v) == 0 else v for v in df[key]]
|
|
102
|
+
|
|
70
103
|
# パースが成功しているかチェックする
|
|
71
104
|
lack = True
|
|
72
105
|
for col in df.columns:
|
|
@@ -87,15 +120,8 @@ class ParseBase:
|
|
|
87
120
|
OPTIONAL_COLUMNS = []
|
|
88
121
|
|
|
89
122
|
@classmethod
|
|
90
|
-
def parse(cls, book_path, sheet_name, raise_if_no_keyword
|
|
91
|
-
return parse_excel(
|
|
92
|
-
book_path,
|
|
93
|
-
sheet_name,
|
|
94
|
-
cls.KEYWORD,
|
|
95
|
-
cls.REQUIRED_COLUMNS,
|
|
96
|
-
cls.OPTIONAL_COLUMNS,
|
|
97
|
-
raise_if_no_keyword,
|
|
98
|
-
)
|
|
123
|
+
def parse(cls, book_path, sheet_name, raise_if_no_keyword) -> pd.DataFrame:
|
|
124
|
+
return parse_excel(book_path, sheet_name, cls.KEYWORD, cls.REQUIRED_COLUMNS, cls.OPTIONAL_COLUMNS, raise_if_no_keyword)
|
|
99
125
|
|
|
100
126
|
|
|
101
127
|
class ParseAsParameter(ParseBase):
|
|
@@ -104,10 +130,11 @@ class ParseAsParameter(ParseBase):
|
|
|
104
130
|
lb = '下限'
|
|
105
131
|
ub = '上限'
|
|
106
132
|
step = 'ステップ'
|
|
133
|
+
choices = '選択肢'
|
|
107
134
|
use = '使用'
|
|
108
135
|
KEYWORD = name
|
|
109
136
|
REQUIRED_COLUMNS = [value, lb, ub]
|
|
110
|
-
OPTIONAL_COLUMNS = [step, use]
|
|
137
|
+
OPTIONAL_COLUMNS = [step, choices, use]
|
|
111
138
|
|
|
112
139
|
|
|
113
140
|
class ParseAsObjective(ParseBase):
|
|
@@ -147,10 +174,3 @@ def search_r(book_path, sheet_name, value):
|
|
|
147
174
|
|
|
148
175
|
def search_c(book_path, sheet_name, value):
|
|
149
176
|
return search_index(book_path, sheet_name, value)[1]
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
if __name__ == '__main__':
|
|
153
|
-
os.chdir(os.path.dirname(__file__))
|
|
154
|
-
print(ParseAsParameter.parse('sample.xlsx', 'Sheet1'))
|
|
155
|
-
print(search_r('sample.xlsx', 'Sheet1', 'X2'))
|
|
156
|
-
print(search_c('sample.xlsx', 'Sheet1', '値'))
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import ast
|
|
2
|
+
import inspect
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
'_is_access_gogh',
|
|
7
|
+
'_is_access_femtet',
|
|
8
|
+
]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _get_scope_indent(source: str) -> int:
|
|
12
|
+
SPACES = [' ', '\t']
|
|
13
|
+
indent = 0
|
|
14
|
+
while True:
|
|
15
|
+
if source[indent] not in SPACES:
|
|
16
|
+
break
|
|
17
|
+
else:
|
|
18
|
+
indent += 1
|
|
19
|
+
return indent
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _remove_indent(source: str, indent: int) -> str: # returns source
|
|
23
|
+
lines = source.splitlines()
|
|
24
|
+
edited_lines = [l[indent:] for l in lines]
|
|
25
|
+
edited_source = '\n'.join(edited_lines)
|
|
26
|
+
return edited_source
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _check_access_femtet_objects(fun, target: str = 'Femtet'):
|
|
30
|
+
|
|
31
|
+
# 関数fのソースコードを取得
|
|
32
|
+
source = inspect.getsource(fun)
|
|
33
|
+
|
|
34
|
+
# ソースコードを抽象構文木(AST)に変換
|
|
35
|
+
try:
|
|
36
|
+
# instanceメソッドなどの場合を想定してインデントを削除
|
|
37
|
+
source = _remove_indent(source, _get_scope_indent(source))
|
|
38
|
+
tree = ast.parse(source)
|
|
39
|
+
|
|
40
|
+
except Exception:
|
|
41
|
+
return False # パースに失敗するからと言ってエラーにするまででもない
|
|
42
|
+
|
|
43
|
+
# if function or staticmethod, 1st argument is Femtet. Find the name.
|
|
44
|
+
varname_contains_femtet = '' # invalid variable name
|
|
45
|
+
for node in ast.walk(tree):
|
|
46
|
+
if isinstance(node, ast.FunctionDef):
|
|
47
|
+
all_arguments: ast.arguments = node.args
|
|
48
|
+
|
|
49
|
+
args: list[ast.arg] = all_arguments.args
|
|
50
|
+
# args.extend(all_arguments.posonlyargs) # 先にこっちを入れるべきかも
|
|
51
|
+
|
|
52
|
+
target_arg = args[0]
|
|
53
|
+
|
|
54
|
+
# if class method or instance method, 2nd argument is it.
|
|
55
|
+
# In this implementation, we cannot detect the FunctionDef is
|
|
56
|
+
# method or not because the part of source code is unindented and parsed.
|
|
57
|
+
if target_arg.arg == 'self' or target_arg.arg == 'cls':
|
|
58
|
+
if len(args) > 1:
|
|
59
|
+
target_arg = args[1]
|
|
60
|
+
else:
|
|
61
|
+
target_arg = None
|
|
62
|
+
|
|
63
|
+
if target_arg is not None:
|
|
64
|
+
varname_contains_femtet = target_arg.arg
|
|
65
|
+
|
|
66
|
+
# check Femtet access
|
|
67
|
+
if target == 'Femtet':
|
|
68
|
+
for node in ast.walk(tree):
|
|
69
|
+
|
|
70
|
+
# by accessing argument directory
|
|
71
|
+
if isinstance(node, ast.Name):
|
|
72
|
+
# found local variables
|
|
73
|
+
node: ast.Name
|
|
74
|
+
if node.id == varname_contains_femtet:
|
|
75
|
+
# found Femtet
|
|
76
|
+
return True
|
|
77
|
+
|
|
78
|
+
# by accessing inside method
|
|
79
|
+
elif isinstance(node, ast.Attribute):
|
|
80
|
+
# found attribute of something
|
|
81
|
+
node: ast.Attribute
|
|
82
|
+
if node.attr == 'Femtet':
|
|
83
|
+
# found **.Femtet.**
|
|
84
|
+
return True
|
|
85
|
+
|
|
86
|
+
# check Gogh access
|
|
87
|
+
elif target == 'Gogh':
|
|
88
|
+
for node in ast.walk(tree):
|
|
89
|
+
if isinstance(node, ast.Attribute):
|
|
90
|
+
if node.attr == 'Gogh':
|
|
91
|
+
# found **.Gogh.**
|
|
92
|
+
node: ast.Attribute
|
|
93
|
+
parent = node.value
|
|
94
|
+
|
|
95
|
+
# by accessing argument directory
|
|
96
|
+
if isinstance(parent, ast.Name):
|
|
97
|
+
# found *.Gogh.**
|
|
98
|
+
parent: ast.Name
|
|
99
|
+
if parent.id == varname_contains_femtet:
|
|
100
|
+
# found Femtet.Gogh.**
|
|
101
|
+
return True
|
|
102
|
+
|
|
103
|
+
# by accessing inside method
|
|
104
|
+
if isinstance(parent, ast.Attribute):
|
|
105
|
+
# found **.*.Gogh.**
|
|
106
|
+
parent: ast.Attribute
|
|
107
|
+
if parent.attr == 'Femtet':
|
|
108
|
+
# found **.Femtet.Gogh.**
|
|
109
|
+
return True
|
|
110
|
+
|
|
111
|
+
# ここまで来たならば target へのアクセスはおそらくない
|
|
112
|
+
return False
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def _is_access_gogh(fun: callable) -> bool:
|
|
116
|
+
return _check_access_femtet_objects(fun, target='Gogh')
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def _is_access_femtet(fun: callable) -> bool:
|
|
120
|
+
return _check_access_femtet_objects(fun, target='Femtet')
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import winreg
|
|
2
2
|
from typing import Final
|
|
3
3
|
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
'_get_autosave_enabled',
|
|
7
|
+
'_set_autosave_enabled',
|
|
8
|
+
]
|
|
9
|
+
|
|
10
|
+
|
|
4
11
|
# レジストリのパスと値の名前
|
|
5
12
|
_REGISTRY_PATH: Final[str] = r"SOFTWARE\Murata Software\Femtet2014\Femtet"
|
|
6
13
|
_VALUE_NAME: Final[str] = "AutoSave"
|