MoleditPy-linux 4.1.0__tar.gz → 4.1.1__tar.gz

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.
Files changed (80) hide show
  1. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/PKG-INFO +5 -5
  2. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/README.md +4 -4
  3. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/pyproject.toml +1 -1
  4. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/MoleditPy_linux.egg-info/PKG-INFO +5 -5
  5. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/calculation_worker.py +60 -12
  6. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/compute_logic.py +3 -3
  7. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/LICENSE +0 -0
  8. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/setup.cfg +0 -0
  9. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/MoleditPy_linux.egg-info/SOURCES.txt +0 -0
  10. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/MoleditPy_linux.egg-info/dependency_links.txt +0 -0
  11. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/MoleditPy_linux.egg-info/entry_points.txt +0 -0
  12. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/MoleditPy_linux.egg-info/requires.txt +0 -0
  13. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/MoleditPy_linux.egg-info/top_level.txt +0 -0
  14. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/__init__.py +0 -0
  15. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/__main__.py +0 -0
  16. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/assets/file_icon.ico +0 -0
  17. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/assets/icon.icns +0 -0
  18. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/assets/icon.ico +0 -0
  19. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/assets/icon.png +0 -0
  20. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/core/__init__.py +0 -0
  21. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/core/mol_geometry.py +0 -0
  22. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/core/molecular_data.py +0 -0
  23. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/main.py +0 -0
  24. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/plugins/__init__.py +0 -0
  25. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/plugins/plugin_interface.py +0 -0
  26. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/plugins/plugin_manager.py +0 -0
  27. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/plugins/plugin_manager_window.py +0 -0
  28. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/__init__.py +0 -0
  29. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/about_dialog.py +0 -0
  30. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/align_plane_dialog.py +0 -0
  31. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/alignment_dialog.py +0 -0
  32. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/analysis_window.py +0 -0
  33. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/angle_dialog.py +0 -0
  34. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/app_state.py +0 -0
  35. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/atom_item.py +0 -0
  36. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/atom_picking.py +0 -0
  37. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/base_picking_dialog.py +0 -0
  38. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/bond_item.py +0 -0
  39. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/bond_length_dialog.py +0 -0
  40. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/color_settings_dialog.py +0 -0
  41. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/constrained_optimization_dialog.py +0 -0
  42. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/custom_interactor_style.py +0 -0
  43. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/custom_qt_interactor.py +0 -0
  44. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/dialog_3d_picking_mixin.py +0 -0
  45. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/dialog_logic.py +0 -0
  46. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/dihedral_dialog.py +0 -0
  47. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/edit_3d_logic.py +0 -0
  48. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/edit_actions_logic.py +0 -0
  49. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/export_logic.py +0 -0
  50. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/geometry_base_dialog.py +0 -0
  51. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/io_logic.py +0 -0
  52. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/main_window.py +0 -0
  53. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/main_window_init.py +0 -0
  54. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/mirror_dialog.py +0 -0
  55. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/molecular_scene_handler.py +0 -0
  56. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/molecule_scene.py +0 -0
  57. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/move_group_dialog.py +0 -0
  58. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/move_selected_atoms_dialog.py +0 -0
  59. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/periodic_table_dialog.py +0 -0
  60. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/planarize_dialog.py +0 -0
  61. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/plugin_menu_manager.py +0 -0
  62. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/settings_dialog.py +0 -0
  63. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/settings_tabs/__init__.py +0 -0
  64. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/settings_tabs/settings_2d_tab.py +0 -0
  65. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/settings_tabs/settings_3d_tabs.py +0 -0
  66. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/settings_tabs/settings_other_tab.py +0 -0
  67. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/settings_tabs/settings_tab_base.py +0 -0
  68. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/string_importers.py +0 -0
  69. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/template_preview_item.py +0 -0
  70. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/template_preview_view.py +0 -0
  71. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/translation_dialog.py +0 -0
  72. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/ui_manager.py +0 -0
  73. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/user_template_dialog.py +0 -0
  74. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/view_3d_logic.py +0 -0
  75. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/ui/zoomable_view.py +0 -0
  76. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/utils/__init__.py +0 -0
  77. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/utils/constants.py +0 -0
  78. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/utils/default_settings.py +0 -0
  79. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/utils/sip_isdeleted_safe.py +0 -0
  80. {moleditpy_linux-4.1.0 → moleditpy_linux-4.1.1}/src/moleditpy_linux/utils/system_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MoleditPy-linux
3
- Version: 4.1.0
3
+ Version: 4.1.1
4
4
  Summary: A cross-platform, simple, and intuitive molecular structure editor built in Python. It allows 2D molecular drawing and 3D structure visualization. It supports exporting structure files for input to DFT calculation software.
5
5
  Author-email: HiroYokoyama <titech.yoko.hiro@gmail.com>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -837,9 +837,9 @@ moleditpy
837
837
  * **3D Visualization (PyVista / pyvistaqt):** 3D rendering is achieved by generating PyVista meshes (spheres and cylinders) from RDKit conformer coordinates. A custom `vtkInteractorStyle` enables direct drag-and-drop editing of atoms in the 3D view.
838
838
  * **Modular Architecture:** The codebase is organized into dedicated packages for `core` logic, `ui` components, and `utils`. The main application logic is decomposed into reusable mixins, ensuring long-term maintainability and easier verification.
839
839
 
840
- ## License
840
+ ## License & Disclaimer
841
841
 
842
- This project is licensed under the **GNU General Public License v3.0 (GPL-v3)**. See the `LICENSE` file for details.
842
+ This project is licensed under the GNU General Public License v3.0 (GPLv3) - see the [LICENSE](LICENSE) file for details. As open-source software, it is provided 'as is' without warranty of any kind, and the author assumes no responsibility or liability for the results. Although outputs have been carefully verified, users are strongly encouraged to independently check and validate them for critical applications (such as publications). If you encounter any bugs, please open an issue.
843
843
 
844
844
  ## Citation
845
845
 
@@ -971,9 +971,9 @@ moleditpy
971
971
  * **化学計算 (RDKit / Open Babel):** 2DデータからRDKit分子オブジェクトを生成し、3D座標生成や分子特性計算を実行します。RDKitでの3D座標生成が失敗した際は、Open Babelにフォールバックします。重い計算処理は別スレッド (`QThread`) で実行し、GUIの応答性を維持しています。
972
972
  * **3D可視化 (PyVista / pyvistaqt):** RDKitのコンフォーマ座標からPyVistaのメッシュ(球や円柱)を生成して描画します。カスタムの`vtkInteractorStyle`を実装し、3Dビュー内での原子の直接的なドラッグ&ドロップ編集を可能にしています。
973
973
 
974
- ## ライセンス
974
+ ## ライセンス & 免責事項
975
975
 
976
- このプロジェクトは **GNU General Public License v3.0 (GPL-v3)** のもとで公開されています。詳細は `LICENSE` ファイルを参照してください。
976
+ このプロジェクトは GNU General Public License v3.0 (GPLv3) のもとでライセンスされています。詳細は [LICENSE](LICENSE) ファイルを参照してください。オープンソースソフトウェアとして、本ソフトウェアは「現状のまま」提供され、いかなる明示または黙示の保証も行いません。また、本ソフトウェアを使用した結果について、作者は一切の責任や義務を負いません。出力結果は慎重に検証されていますが、学術論文の作成など重要な用途においては、ユーザーご自身で結果を独立して確認および検証することを強くお勧めします。バグに遭遇した場合は、Issueを作成してください。
977
977
 
978
978
  ## 引用
979
979
 
@@ -134,9 +134,9 @@ moleditpy
134
134
  * **3D Visualization (PyVista / pyvistaqt):** 3D rendering is achieved by generating PyVista meshes (spheres and cylinders) from RDKit conformer coordinates. A custom `vtkInteractorStyle` enables direct drag-and-drop editing of atoms in the 3D view.
135
135
  * **Modular Architecture:** The codebase is organized into dedicated packages for `core` logic, `ui` components, and `utils`. The main application logic is decomposed into reusable mixins, ensuring long-term maintainability and easier verification.
136
136
 
137
- ## License
137
+ ## License & Disclaimer
138
138
 
139
- This project is licensed under the **GNU General Public License v3.0 (GPL-v3)**. See the `LICENSE` file for details.
139
+ This project is licensed under the GNU General Public License v3.0 (GPLv3) - see the [LICENSE](LICENSE) file for details. As open-source software, it is provided 'as is' without warranty of any kind, and the author assumes no responsibility or liability for the results. Although outputs have been carefully verified, users are strongly encouraged to independently check and validate them for critical applications (such as publications). If you encounter any bugs, please open an issue.
140
140
 
141
141
  ## Citation
142
142
 
@@ -268,9 +268,9 @@ moleditpy
268
268
  * **化学計算 (RDKit / Open Babel):** 2DデータからRDKit分子オブジェクトを生成し、3D座標生成や分子特性計算を実行します。RDKitでの3D座標生成が失敗した際は、Open Babelにフォールバックします。重い計算処理は別スレッド (`QThread`) で実行し、GUIの応答性を維持しています。
269
269
  * **3D可視化 (PyVista / pyvistaqt):** RDKitのコンフォーマ座標からPyVistaのメッシュ(球や円柱)を生成して描画します。カスタムの`vtkInteractorStyle`を実装し、3Dビュー内での原子の直接的なドラッグ&ドロップ編集を可能にしています。
270
270
 
271
- ## ライセンス
271
+ ## ライセンス & 免責事項
272
272
 
273
- このプロジェクトは **GNU General Public License v3.0 (GPL-v3)** のもとで公開されています。詳細は `LICENSE` ファイルを参照してください。
273
+ このプロジェクトは GNU General Public License v3.0 (GPLv3) のもとでライセンスされています。詳細は [LICENSE](LICENSE) ファイルを参照してください。オープンソースソフトウェアとして、本ソフトウェアは「現状のまま」提供され、いかなる明示または黙示の保証も行いません。また、本ソフトウェアを使用した結果について、作者は一切の責任や義務を負いません。出力結果は慎重に検証されていますが、学術論文の作成など重要な用途においては、ユーザーご自身で結果を独立して確認および検証することを強くお勧めします。バグに遭遇した場合は、Issueを作成してください。
274
274
 
275
275
  ## 引用
276
276
 
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
  [project]
6
6
  name = "MoleditPy-linux"
7
7
 
8
- version = "4.1.0"
8
+ version = "4.1.1"
9
9
 
10
10
  license = {file = "LICENSE"}
11
11
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MoleditPy-linux
3
- Version: 4.1.0
3
+ Version: 4.1.1
4
4
  Summary: A cross-platform, simple, and intuitive molecular structure editor built in Python. It allows 2D molecular drawing and 3D structure visualization. It supports exporting structure files for input to DFT calculation software.
5
5
  Author-email: HiroYokoyama <titech.yoko.hiro@gmail.com>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -837,9 +837,9 @@ moleditpy
837
837
  * **3D Visualization (PyVista / pyvistaqt):** 3D rendering is achieved by generating PyVista meshes (spheres and cylinders) from RDKit conformer coordinates. A custom `vtkInteractorStyle` enables direct drag-and-drop editing of atoms in the 3D view.
838
838
  * **Modular Architecture:** The codebase is organized into dedicated packages for `core` logic, `ui` components, and `utils`. The main application logic is decomposed into reusable mixins, ensuring long-term maintainability and easier verification.
839
839
 
840
- ## License
840
+ ## License & Disclaimer
841
841
 
842
- This project is licensed under the **GNU General Public License v3.0 (GPL-v3)**. See the `LICENSE` file for details.
842
+ This project is licensed under the GNU General Public License v3.0 (GPLv3) - see the [LICENSE](LICENSE) file for details. As open-source software, it is provided 'as is' without warranty of any kind, and the author assumes no responsibility or liability for the results. Although outputs have been carefully verified, users are strongly encouraged to independently check and validate them for critical applications (such as publications). If you encounter any bugs, please open an issue.
843
843
 
844
844
  ## Citation
845
845
 
@@ -971,9 +971,9 @@ moleditpy
971
971
  * **化学計算 (RDKit / Open Babel):** 2DデータからRDKit分子オブジェクトを生成し、3D座標生成や分子特性計算を実行します。RDKitでの3D座標生成が失敗した際は、Open Babelにフォールバックします。重い計算処理は別スレッド (`QThread`) で実行し、GUIの応答性を維持しています。
972
972
  * **3D可視化 (PyVista / pyvistaqt):** RDKitのコンフォーマ座標からPyVistaのメッシュ(球や円柱)を生成して描画します。カスタムの`vtkInteractorStyle`を実装し、3Dビュー内での原子の直接的なドラッグ&ドロップ編集を可能にしています。
973
973
 
974
- ## ライセンス
974
+ ## ライセンス & 免責事項
975
975
 
976
- このプロジェクトは **GNU General Public License v3.0 (GPL-v3)** のもとで公開されています。詳細は `LICENSE` ファイルを参照してください。
976
+ このプロジェクトは GNU General Public License v3.0 (GPLv3) のもとでライセンスされています。詳細は [LICENSE](LICENSE) ファイルを参照してください。オープンソースソフトウェアとして、本ソフトウェアは「現状のまま」提供され、いかなる明示または黙示の保証も行いません。また、本ソフトウェアを使用した結果について、作者は一切の責任や義務を負いません。出力結果は慎重に検証されていますが、学術論文の作成など重要な用途においては、ユーザーご自身で結果を独立して確認および検証することを強くお勧めします。バグに遭遇した場合は、Issueを作成してください。
977
977
 
978
978
  ## 引用
979
979
 
@@ -548,7 +548,22 @@ def _perform_direct_conversion(
548
548
  _safe_status,
549
549
  options=options if backend == "RDKIT" else None,
550
550
  ):
551
- raise RuntimeError(f"Optimization with {opt_method} failed.")
551
+ fallback_success = False
552
+ if backend == "RDKIT" and "MMFF" in method_key:
553
+ _safe_status("MMFF optimization failed. Auto-falling back to UFF...")
554
+ fallback_success = opt_func(
555
+ mol, "UFF", _check_halted, _safe_status, options=options
556
+ )
557
+ if fallback_success:
558
+ with contextlib.suppress(Exception):
559
+ mol.SetProp("_pme_optimization_method", "UFF_RDKIT")
560
+
561
+ if not fallback_success:
562
+ _safe_status(
563
+ "Warning: Optimization failed. Using unoptimized structure."
564
+ )
565
+ with contextlib.suppress(Exception):
566
+ mol.ClearProp("_pme_optimization_method")
552
567
 
553
568
  if _check_halted():
554
569
  raise WorkerHaltError("Halted")
@@ -664,15 +679,30 @@ print(ob_mol.write("mol"))
664
679
  _safe_status,
665
680
  options=options if backend == "RDKIT" else None,
666
681
  ):
667
- _safe_status("Warning: Optimization failed. Using unoptimized structure.")
668
- # Best-effort property cleanup if optimization was skipped
669
- with contextlib.suppress(AttributeError, RuntimeError, TypeError):
670
- rd_mol.ClearProp("_pme_optimization_method")
682
+ fallback_success = False
683
+ if backend == "RDKIT" and "MMFF" in method_key:
684
+ _safe_status("MMFF optimization failed. Auto-falling back to UFF...")
685
+ fallback_success = opt_func(
686
+ rd_mol, "UFF", _check_halted, _safe_status, options=options
687
+ )
688
+ if fallback_success:
689
+ with contextlib.suppress(Exception):
690
+ rd_mol.SetProp("_pme_optimization_method", "UFF_RDKIT")
691
+
692
+ if not fallback_success:
693
+ _safe_status(
694
+ "Warning: Optimization failed. Using unoptimized structure."
695
+ )
696
+ with contextlib.suppress(Exception):
697
+ rd_mol.ClearProp("_pme_optimization_method")
671
698
 
672
699
  if _check_halted():
673
700
  raise WorkerHaltError("Halted")
674
701
  # Final status message before finishing (to ensure it doesn't overwrite error/halt messages)
675
- opt_label = _OPT_METHOD_LABELS.get(opt_method, opt_method)
702
+ final_opt = "Unoptimized"
703
+ if rd_mol.HasProp("_pme_optimization_method"):
704
+ final_opt = rd_mol.GetProp("_pme_optimization_method")
705
+ opt_label = _OPT_METHOD_LABELS.get(final_opt, final_opt)
676
706
  _safe_status(f"Process completed (Open Babel Conversion / {opt_label}).")
677
707
  _safe_finished((worker_id, rd_mol))
678
708
  return True
@@ -925,9 +955,22 @@ class CalculationWorker(QObject):
925
955
  _safe_status,
926
956
  options=options if backend == "RDKIT" else None,
927
957
  ):
928
- _safe_status("Warning: Optimization failed. Using unoptimized structure.")
929
- with contextlib.suppress(Exception):
930
- mol.ClearProp("_pme_optimization_method")
958
+ fallback_success = False
959
+ if backend == "RDKIT" and "MMFF" in method_key:
960
+ _safe_status("MMFF optimization failed. Auto-falling back to UFF...")
961
+ fallback_success = opt_func(
962
+ mol, "UFF", _check_halted, _safe_status, options=options
963
+ )
964
+ if fallback_success:
965
+ with contextlib.suppress(Exception):
966
+ mol.SetProp("_pme_optimization_method", "UFF_RDKIT")
967
+
968
+ if not fallback_success:
969
+ _safe_status(
970
+ "Warning: Optimization failed. Using unoptimized structure."
971
+ )
972
+ with contextlib.suppress(Exception):
973
+ mol.ClearProp("_pme_optimization_method")
931
974
 
932
975
  # Final stereo restoration check
933
976
  for b_idx, s, satoms in orig_stereo:
@@ -939,7 +982,10 @@ class CalculationWorker(QObject):
939
982
  if _check_halted():
940
983
  raise WorkerHaltError("Halted")
941
984
  # Final status message before finishing (to ensure it doesn't overwrite error/halt messages)
942
- opt_label = _OPT_METHOD_LABELS.get(opt_method, opt_method)
985
+ final_opt = "Unoptimized"
986
+ if mol.HasProp("_pme_optimization_method"):
987
+ final_opt = mol.GetProp("_pme_optimization_method")
988
+ opt_label = _OPT_METHOD_LABELS.get(final_opt, final_opt)
943
989
  _safe_status(f"Process completed (RDKit Conversion / {opt_label}).")
944
990
  _safe_finished((w_id, mol))
945
991
  return True
@@ -972,9 +1018,11 @@ class CalculationWorker(QObject):
972
1018
  )
973
1019
  # Final status message before finishing (to ensure it doesn't overwrite error/halt messages)
974
1020
  _safe_status = helpers["status"]
975
- opt_method = (options or {}).get("optimization_method") or "MMFF94s_RDKIT"
976
1021
  if (options or {}).get("do_optimize", True):
977
- opt_label = _OPT_METHOD_LABELS.get(opt_method, opt_method)
1022
+ final_opt = "Unoptimized"
1023
+ if mol.HasProp("_pme_optimization_method"):
1024
+ final_opt = mol.GetProp("_pme_optimization_method")
1025
+ opt_label = _OPT_METHOD_LABELS.get(final_opt, final_opt)
978
1026
  _safe_status(f"Process completed (Direct 2D->3D Conversion / {opt_label}).")
979
1027
  else:
980
1028
  _safe_status("Process completed (Direct 2D->3D Conversion).")
@@ -484,13 +484,13 @@ class ComputeManager:
484
484
  method_key = None
485
485
  if mol and mol.HasProp("_pme_optimization_method"):
486
486
  method_key = mol.GetProp("_pme_optimization_method")
487
- if not method_key:
488
- method_key = self.host.init_manager.optimization_method
489
487
  if method_key:
490
488
  labels = self.host.init_manager.opt3d_method_labels or {}
491
489
  self.last_successful_optimization_method = labels.get(
492
490
  method_key, method_key
493
491
  )
492
+ else:
493
+ self.last_successful_optimization_method = "Unoptimized"
494
494
  except (AttributeError, TypeError):
495
495
  # Safe defensive fallback catching AttributeError, TypeError
496
496
  pass
@@ -539,7 +539,7 @@ class ComputeManager:
539
539
  "Retry with UFF?",
540
540
  f"{msg}\n\nWould you like to retry using UFF (RDKit) instead?",
541
541
  QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
542
- QMessageBox.StandardButton.No,
542
+ QMessageBox.StandardButton.Yes,
543
543
  )
544
544
  if reply == QMessageBox.StandardButton.Yes:
545
545
  self.optimize_3d_structure("UFF_RDKIT")
File without changes