MoleditPy-linux 4.8.2__tar.gz → 4.8.3__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.
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/PKG-INFO +1 -1
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/pyproject.toml +1 -1
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/MoleditPy_linux.egg-info/PKG-INFO +1 -1
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/core/mol_geometry.py +2 -2
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/core/molecular_data.py +1 -1
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/main.py +2 -2
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/plugins/plugin_interface.py +12 -10
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/plugins/plugin_manager.py +30 -15
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/analysis_window.py +8 -5
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/app_state.py +13 -7
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/base_picking_dialog.py +2 -2
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/calculation_worker.py +34 -26
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/compute_logic.py +23 -6
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/constrained_optimization_dialog.py +7 -5
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/custom_interactor_style.py +4 -1
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/custom_qt_interactor.py +5 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/dialog_3d_picking_mixin.py +8 -1
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/edit_actions_logic.py +22 -4
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/export_logic.py +2 -2
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/io_logic.py +27 -8
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/main_window_init.py +1 -1
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/molecular_scene_handler.py +4 -4
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/molecule_scene.py +6 -2
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/move_group_dialog.py +3 -3
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/move_selected_atoms_dialog.py +3 -3
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/planarize_dialog.py +1 -1
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/plugin_menu_manager.py +3 -1
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/string_importers.py +7 -7
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/template_preview_item.py +2 -2
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/translation_dialog.py +14 -2
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/view_3d_logic.py +20 -20
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/LICENSE +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/README.md +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/setup.cfg +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/MoleditPy_linux.egg-info/SOURCES.txt +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/MoleditPy_linux.egg-info/dependency_links.txt +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/MoleditPy_linux.egg-info/entry_points.txt +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/MoleditPy_linux.egg-info/requires.txt +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/MoleditPy_linux.egg-info/top_level.txt +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/__init__.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/__main__.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/assets/file_icon.ico +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/assets/icon.icns +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/assets/icon.ico +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/assets/icon.png +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/core/__init__.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/plugins/__init__.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/plugins/plugin_manager_window.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/__init__.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/about_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/align_plane_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/alignment_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/angle_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/atom_item.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/atom_picking.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/bond_item.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/bond_length_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/chain_mixin.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/color_settings_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/dialog_logic.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/dihedral_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/edit_3d_logic.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/geometry_base_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/main_window.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/mirror_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/periodic_table_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/preview_molecule.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/settings_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/settings_tabs/__init__.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/settings_tabs/settings_2d_tab.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/settings_tabs/settings_3d_tabs.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/settings_tabs/settings_other_tab.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/settings_tabs/settings_tab_base.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/template_preview_view.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/ui_manager.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/user_template_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/zoomable_view.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/utils/__init__.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/utils/constants.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/utils/default_settings.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/utils/hit_radius.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/utils/sip_isdeleted_safe.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/utils/suppress_log.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/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.8.
|
|
3
|
+
Version: 4.8.3
|
|
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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: MoleditPy-linux
|
|
3
|
-
Version: 4.8.
|
|
3
|
+
Version: 4.8.3
|
|
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
|
|
@@ -593,9 +593,9 @@ def _identify_problems_rdkit(
|
|
|
593
593
|
|
|
594
594
|
def optimize_2d_coords(mol: Chem.Mol) -> Dict[int, Tuple[float, float]]:
|
|
595
595
|
"""Generate 2D coordinates using RDKit and return a map of (x, y) tuples."""
|
|
596
|
-
from rdkit.Chem import
|
|
596
|
+
from rdkit.Chem import rdDepictor
|
|
597
597
|
|
|
598
|
-
|
|
598
|
+
rdDepictor.Compute2DCoords(mol)
|
|
599
599
|
conf = mol.GetConformer()
|
|
600
600
|
new_positions = {}
|
|
601
601
|
for rdkit_atom in mol.GetAtoms():
|
|
@@ -20,7 +20,7 @@ import sys
|
|
|
20
20
|
import argparse
|
|
21
21
|
import time
|
|
22
22
|
import traceback
|
|
23
|
-
from typing import Any, Dict, Optional
|
|
23
|
+
from typing import Any, Dict, Optional, Set
|
|
24
24
|
|
|
25
25
|
from .utils.constants import VERSION
|
|
26
26
|
|
|
@@ -81,7 +81,7 @@ class _ErrorDialogHandler(logging.Handler):
|
|
|
81
81
|
# signature -> monotonic timestamp of its last shown dialog.
|
|
82
82
|
self._last_shown: Dict[str, float] = {}
|
|
83
83
|
# Held so a non-blocking box is not garbage-collected before it closes.
|
|
84
|
-
self._open_boxes:
|
|
84
|
+
self._open_boxes: Set[QMessageBox] = set()
|
|
85
85
|
self._log_path = log_path
|
|
86
86
|
|
|
87
87
|
def emit(self, record: logging.LogRecord) -> None:
|
{moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/plugins/plugin_interface.py
RENAMED
|
@@ -27,7 +27,7 @@ class PluginContext:
|
|
|
27
27
|
def add_menu_action(
|
|
28
28
|
self,
|
|
29
29
|
path: str,
|
|
30
|
-
callback: Callable,
|
|
30
|
+
callback: Callable[..., Any],
|
|
31
31
|
text: Optional[str] = None,
|
|
32
32
|
icon: Optional[str] = None,
|
|
33
33
|
shortcut: Optional[str] = None,
|
|
@@ -57,8 +57,8 @@ class PluginContext:
|
|
|
57
57
|
def register_menu_action(
|
|
58
58
|
self,
|
|
59
59
|
path: str,
|
|
60
|
-
text_or_callback: Union[str, Callable],
|
|
61
|
-
callback: Optional[Callable] = None,
|
|
60
|
+
text_or_callback: Union[str, Callable[..., Any]],
|
|
61
|
+
callback: Optional[Callable[..., Any]] = None,
|
|
62
62
|
icon: Optional[str] = None,
|
|
63
63
|
shortcut: Optional[str] = None,
|
|
64
64
|
) -> None:
|
|
@@ -76,7 +76,7 @@ class PluginContext:
|
|
|
76
76
|
def add_plugin_menu(
|
|
77
77
|
self,
|
|
78
78
|
path: str,
|
|
79
|
-
callback: Callable,
|
|
79
|
+
callback: Callable[..., Any],
|
|
80
80
|
text: Optional[str] = None,
|
|
81
81
|
icon: Optional[str] = None,
|
|
82
82
|
shortcut: Optional[str] = None,
|
|
@@ -103,7 +103,7 @@ class PluginContext:
|
|
|
103
103
|
|
|
104
104
|
def add_toolbar_action(
|
|
105
105
|
self,
|
|
106
|
-
callback: Callable,
|
|
106
|
+
callback: Callable[..., Any],
|
|
107
107
|
text: str,
|
|
108
108
|
icon: Optional[str] = None,
|
|
109
109
|
tooltip: Optional[str] = None,
|
|
@@ -262,7 +262,7 @@ class PluginContext:
|
|
|
262
262
|
if mw and hasattr(mw, "view_3d_manager") and mw.view_3d_manager.plotter:
|
|
263
263
|
mw.view_3d_manager.plotter.reset_camera()
|
|
264
264
|
|
|
265
|
-
def add_export_action(self, label: str, callback: Callable) -> None:
|
|
265
|
+
def add_export_action(self, label: str, callback: Callable[..., Any]) -> None:
|
|
266
266
|
"""
|
|
267
267
|
Register a custom export action.
|
|
268
268
|
|
|
@@ -303,7 +303,7 @@ class PluginContext:
|
|
|
303
303
|
self._plugin_name, extension, callback, priority
|
|
304
304
|
)
|
|
305
305
|
|
|
306
|
-
def add_analysis_tool(self, label: str, callback: Callable) -> None:
|
|
306
|
+
def add_analysis_tool(self, label: str, callback: Callable[..., Any]) -> None:
|
|
307
307
|
"""
|
|
308
308
|
Register a tool in the Analysis menu.
|
|
309
309
|
|
|
@@ -313,7 +313,7 @@ class PluginContext:
|
|
|
313
313
|
"""
|
|
314
314
|
self._manager.register_analysis_tool(self._plugin_name, label, callback)
|
|
315
315
|
|
|
316
|
-
def register_save_handler(self, callback: Callable[[],
|
|
316
|
+
def register_save_handler(self, callback: Callable[[], Dict[str, Any]]) -> None:
|
|
317
317
|
"""
|
|
318
318
|
Register a callback to save state into the project file.
|
|
319
319
|
|
|
@@ -322,7 +322,7 @@ class PluginContext:
|
|
|
322
322
|
"""
|
|
323
323
|
self._manager.register_save_handler(self._plugin_name, callback)
|
|
324
324
|
|
|
325
|
-
def register_load_handler(self, callback: Callable[[
|
|
325
|
+
def register_load_handler(self, callback: Callable[[Dict[str, Any]], None]) -> None:
|
|
326
326
|
"""
|
|
327
327
|
Register a callback to restore state from the project file.
|
|
328
328
|
|
|
@@ -331,7 +331,9 @@ class PluginContext:
|
|
|
331
331
|
"""
|
|
332
332
|
self._manager.register_load_handler(self._plugin_name, callback)
|
|
333
333
|
|
|
334
|
-
def register_3d_context_menu(
|
|
334
|
+
def register_3d_context_menu(
|
|
335
|
+
self, callback: Callable[..., Any], label: str
|
|
336
|
+
) -> None:
|
|
335
337
|
"""Deprecated: This method does nothing. Kept for backward compatibility."""
|
|
336
338
|
import warnings
|
|
337
339
|
|
{moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/plugins/plugin_manager.py
RENAMED
|
@@ -92,8 +92,8 @@ class PluginManager:
|
|
|
92
92
|
self.optimization_methods: Dict[str, Dict[str, Any]] = {}
|
|
93
93
|
self.file_openers: Dict[str, List[Dict[str, Any]]] = {}
|
|
94
94
|
self.analysis_tools: List[Dict[str, Any]] = []
|
|
95
|
-
self.save_handlers: Dict[str, Callable] = {}
|
|
96
|
-
self.load_handlers: Dict[str, Callable] = {}
|
|
95
|
+
self.save_handlers: Dict[str, Callable[..., Any]] = {}
|
|
96
|
+
self.load_handlers: Dict[str, Callable[..., Any]] = {}
|
|
97
97
|
self.custom_3d_styles: Dict[str, Dict[str, Any]] = {}
|
|
98
98
|
self.document_reset_handlers: List[Dict[str, Any]] = []
|
|
99
99
|
self.atom_drag_handlers: List[Dict[str, Any]] = []
|
|
@@ -447,7 +447,7 @@ class PluginManager:
|
|
|
447
447
|
self,
|
|
448
448
|
plugin_name: str,
|
|
449
449
|
path: str,
|
|
450
|
-
callback: Callable,
|
|
450
|
+
callback: Callable[..., Any],
|
|
451
451
|
text: str,
|
|
452
452
|
icon: str,
|
|
453
453
|
shortcut: str,
|
|
@@ -471,7 +471,12 @@ class PluginManager:
|
|
|
471
471
|
)
|
|
472
472
|
|
|
473
473
|
def register_toolbar_action(
|
|
474
|
-
self,
|
|
474
|
+
self,
|
|
475
|
+
plugin_name: str,
|
|
476
|
+
callback: Callable[..., Any],
|
|
477
|
+
text: str,
|
|
478
|
+
icon: str,
|
|
479
|
+
tooltip: str,
|
|
475
480
|
) -> None:
|
|
476
481
|
"""Register a plugin toolbar button with its callback and display metadata."""
|
|
477
482
|
self.toolbar_actions.append(
|
|
@@ -485,7 +490,7 @@ class PluginManager:
|
|
|
485
490
|
)
|
|
486
491
|
|
|
487
492
|
def register_drop_handler(
|
|
488
|
-
self, plugin_name: str, callback: Callable, priority: int
|
|
493
|
+
self, plugin_name: str, callback: Callable[..., Any], priority: int
|
|
489
494
|
) -> None:
|
|
490
495
|
"""Register a drag-and-drop handler with a given priority."""
|
|
491
496
|
self.drop_handlers.append(
|
|
@@ -495,7 +500,7 @@ class PluginManager:
|
|
|
495
500
|
self.drop_handlers.sort(key=lambda x: x["priority"], reverse=True)
|
|
496
501
|
|
|
497
502
|
def register_export_action(
|
|
498
|
-
self, plugin_name: str, label: str, callback: Callable
|
|
503
|
+
self, plugin_name: str, label: str, callback: Callable[..., Any]
|
|
499
504
|
) -> None:
|
|
500
505
|
"""Register a plugin export action with its label and callback."""
|
|
501
506
|
self.export_actions.append(
|
|
@@ -503,7 +508,7 @@ class PluginManager:
|
|
|
503
508
|
)
|
|
504
509
|
|
|
505
510
|
def register_optimization_method(
|
|
506
|
-
self, plugin_name: str, method_name: str, callback: Callable
|
|
511
|
+
self, plugin_name: str, method_name: str, callback: Callable[..., Any]
|
|
507
512
|
) -> None:
|
|
508
513
|
"""Register a named 3D optimization method provided by a plugin."""
|
|
509
514
|
method_key = method_name.upper()
|
|
@@ -520,7 +525,11 @@ class PluginManager:
|
|
|
520
525
|
)
|
|
521
526
|
|
|
522
527
|
def register_file_opener(
|
|
523
|
-
self,
|
|
528
|
+
self,
|
|
529
|
+
plugin_name: str,
|
|
530
|
+
extension: str,
|
|
531
|
+
callback: Callable[..., Any],
|
|
532
|
+
priority: int = 0,
|
|
524
533
|
) -> None:
|
|
525
534
|
"""Register a file-type handler for the given extension."""
|
|
526
535
|
# Normalize extension to lowercase
|
|
@@ -540,7 +549,7 @@ class PluginManager:
|
|
|
540
549
|
|
|
541
550
|
# Analysis Tools registration
|
|
542
551
|
def register_analysis_tool(
|
|
543
|
-
self, plugin_name: str, label: str, callback: Callable
|
|
552
|
+
self, plugin_name: str, label: str, callback: Callable[..., Any]
|
|
544
553
|
) -> None:
|
|
545
554
|
"""Register a plugin analysis tool with its label and callback."""
|
|
546
555
|
self.analysis_tools.append(
|
|
@@ -548,16 +557,20 @@ class PluginManager:
|
|
|
548
557
|
)
|
|
549
558
|
|
|
550
559
|
# State Persistence registration
|
|
551
|
-
def register_save_handler(
|
|
560
|
+
def register_save_handler(
|
|
561
|
+
self, plugin_name: str, callback: Callable[..., Any]
|
|
562
|
+
) -> None:
|
|
552
563
|
"""Register a plugin session-save callback."""
|
|
553
564
|
self.save_handlers[plugin_name] = callback
|
|
554
565
|
|
|
555
|
-
def register_load_handler(
|
|
566
|
+
def register_load_handler(
|
|
567
|
+
self, plugin_name: str, callback: Callable[..., Any]
|
|
568
|
+
) -> None:
|
|
556
569
|
"""Register a plugin session-load callback."""
|
|
557
570
|
self.load_handlers[plugin_name] = callback
|
|
558
571
|
|
|
559
572
|
def register_3d_style(
|
|
560
|
-
self, plugin_name: str, style_name: str, callback: Callable
|
|
573
|
+
self, plugin_name: str, style_name: str, callback: Callable[..., Any]
|
|
561
574
|
) -> None:
|
|
562
575
|
"""Register a named custom 3D rendering style."""
|
|
563
576
|
self.custom_3d_styles[style_name] = {
|
|
@@ -566,14 +579,16 @@ class PluginManager:
|
|
|
566
579
|
}
|
|
567
580
|
|
|
568
581
|
def register_document_reset_handler(
|
|
569
|
-
self, plugin_name: str, callback: Callable
|
|
582
|
+
self, plugin_name: str, callback: Callable[..., Any]
|
|
570
583
|
) -> None:
|
|
571
584
|
"""Register callback to be invoked when a new document is created."""
|
|
572
585
|
self.document_reset_handlers.append(
|
|
573
586
|
{"plugin": plugin_name, "callback": callback}
|
|
574
587
|
)
|
|
575
588
|
|
|
576
|
-
def register_atom_drag_handler(
|
|
589
|
+
def register_atom_drag_handler(
|
|
590
|
+
self, plugin_name: str, callback: Callable[..., Any]
|
|
591
|
+
) -> None:
|
|
577
592
|
"""Register a handler called during 3D atom/group dragging."""
|
|
578
593
|
self.atom_drag_handlers.append({"plugin": plugin_name, "callback": callback})
|
|
579
594
|
|
|
@@ -676,7 +691,7 @@ class PluginManager:
|
|
|
676
691
|
self,
|
|
677
692
|
event_type: str,
|
|
678
693
|
atom_indices: List[int],
|
|
679
|
-
positions: Dict[int,
|
|
694
|
+
positions: Dict[int, Tuple[float, ...]],
|
|
680
695
|
) -> None:
|
|
681
696
|
"""Call all registered atom drag handlers."""
|
|
682
697
|
for handler in self.atom_drag_handlers:
|
|
@@ -75,7 +75,7 @@ class AnalysisWindow(QDialog):
|
|
|
75
75
|
total_atoms = len(xyz_atoms)
|
|
76
76
|
num_heavy_atoms = 0
|
|
77
77
|
|
|
78
|
-
for symbol,
|
|
78
|
+
for symbol, _x, _y, _z in xyz_atoms:
|
|
79
79
|
atom_counts[symbol] = atom_counts.get(symbol, 0) + 1
|
|
80
80
|
if symbol != "H": # Non-hydrogen
|
|
81
81
|
num_heavy_atoms += 1
|
|
@@ -154,12 +154,15 @@ class AnalysisWindow(QDialog):
|
|
|
154
154
|
|
|
155
155
|
# Calculate various properties
|
|
156
156
|
mol_formula = rdMolDescriptors.CalcMolFormula(self.mol)
|
|
157
|
-
|
|
158
|
-
|
|
157
|
+
# Descriptors.MolWt is generated at import time from rdkit's
|
|
158
|
+
# descriptor table, so no stub can declare it; the rest have
|
|
159
|
+
# direct rdMolDescriptors equivalents used elsewhere here.
|
|
160
|
+
mol_wt = Descriptors.MolWt(self.mol) # type: ignore[attr-defined]
|
|
161
|
+
exact_mw = rdMolDescriptors.CalcExactMolWt(self.mol)
|
|
159
162
|
num_heavy_atoms = self.mol.GetNumHeavyAtoms()
|
|
160
163
|
num_rings = rdMolDescriptors.CalcNumRings(self.mol)
|
|
161
|
-
log_p =
|
|
162
|
-
tpsa =
|
|
164
|
+
log_p = rdMolDescriptors.CalcCrippenDescriptors(self.mol)[0]
|
|
165
|
+
tpsa = rdMolDescriptors.CalcTPSA(self.mol)
|
|
163
166
|
num_h_donors = rdMolDescriptors.CalcNumHBD(self.mol)
|
|
164
167
|
num_h_acceptors = rdMolDescriptors.CalcNumHBA(self.mol)
|
|
165
168
|
|
|
@@ -19,7 +19,7 @@ import copy
|
|
|
19
19
|
import logging
|
|
20
20
|
import os
|
|
21
21
|
from ..utils.suppress_log import suppress_log
|
|
22
|
-
from typing import Any, Dict, Optional, Tuple
|
|
22
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
import numpy as np
|
|
@@ -43,7 +43,7 @@ if TYPE_CHECKING:
|
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
# --- Class Definition ---
|
|
46
|
-
def _serialize_constraints(constraints:
|
|
46
|
+
def _serialize_constraints(constraints: List[Any]) -> List[List[Any]]:
|
|
47
47
|
"""Convert internal constraint tuples to JSON-serializable lists."""
|
|
48
48
|
result = []
|
|
49
49
|
for const in constraints:
|
|
@@ -54,7 +54,7 @@ def _serialize_constraints(constraints: list) -> list:
|
|
|
54
54
|
return result
|
|
55
55
|
|
|
56
56
|
|
|
57
|
-
def _deserialize_constraints(raw:
|
|
57
|
+
def _deserialize_constraints(raw: List[Any]) -> List[Tuple[Any, ...]]:
|
|
58
58
|
"""Convert JSON-loaded constraint lists back to internal tuples."""
|
|
59
59
|
result = []
|
|
60
60
|
for const in raw:
|
|
@@ -228,7 +228,7 @@ class StateManager:
|
|
|
228
228
|
if self.host.view_3d_manager.plotter and not getattr(
|
|
229
229
|
self.host, "is_restoring_state", False
|
|
230
230
|
):
|
|
231
|
-
self.host.view_3d_manager.plotter.reset_camera()
|
|
231
|
+
self.host.view_3d_manager.plotter.reset_camera() # type: ignore[call-arg]
|
|
232
232
|
|
|
233
233
|
self.host.ui_manager.enable_3d_features(True)
|
|
234
234
|
self.host.view_3d_manager.setup_3d_hover()
|
|
@@ -481,7 +481,9 @@ class StateManager:
|
|
|
481
481
|
json_data["molecular_info"] = {
|
|
482
482
|
"num_atoms": self.host.view_3d_manager.current_mol.GetNumAtoms(),
|
|
483
483
|
"num_bonds": self.host.view_3d_manager.current_mol.GetNumBonds(),
|
|
484
|
-
|
|
484
|
+
# Generated at import time from rdkit's descriptor
|
|
485
|
+
# table, so no stub can declare it.
|
|
486
|
+
"molecular_weight": Descriptors.MolWt( # type: ignore[attr-defined]
|
|
485
487
|
self.host.view_3d_manager.current_mol
|
|
486
488
|
),
|
|
487
489
|
"formula": rdMolDescriptors.CalcMolFormula(
|
|
@@ -620,7 +622,11 @@ class StateManager:
|
|
|
620
622
|
mol_base64 = structure_3d.get("mol_binary_base64")
|
|
621
623
|
if mol_base64:
|
|
622
624
|
mol_binary = base64.b64decode(mol_base64.encode("ascii"))
|
|
623
|
-
|
|
625
|
+
# Chem.Mol accepts a pickled binary block at runtime;
|
|
626
|
+
# the stub only overloads Mol/str.
|
|
627
|
+
self.host.set_current_molecule(
|
|
628
|
+
Chem.Mol(mol_binary) # type: ignore[call-overload]
|
|
629
|
+
)
|
|
624
630
|
if self.host.view_3d_manager.current_mol:
|
|
625
631
|
# Set 3D coordinates
|
|
626
632
|
if self.host.view_3d_manager.current_mol.GetNumConformers() > 0:
|
|
@@ -686,7 +692,7 @@ class StateManager:
|
|
|
686
692
|
self.host.set_is_2d_editable(True)
|
|
687
693
|
|
|
688
694
|
if self.host.view_3d_manager.plotter:
|
|
689
|
-
self.host.view_3d_manager.plotter.reset_camera()
|
|
695
|
+
self.host.view_3d_manager.plotter.reset_camera() # type: ignore[call-arg]
|
|
690
696
|
|
|
691
697
|
# Enable 3D-related UI
|
|
692
698
|
try:
|
{moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/base_picking_dialog.py
RENAMED
|
@@ -11,7 +11,7 @@ DOI: 10.5281/zenodo.17268532
|
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
13
|
import logging
|
|
14
|
-
from typing import
|
|
14
|
+
from typing import Any, List, Optional, Union, TYPE_CHECKING
|
|
15
15
|
|
|
16
16
|
import numpy as np
|
|
17
17
|
from PyQt6.QtCore import Qt, QTimer
|
|
@@ -25,7 +25,7 @@ if TYPE_CHECKING:
|
|
|
25
25
|
from .main_window import MainWindow
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
class SelectionList(
|
|
28
|
+
class SelectionList(List[int]):
|
|
29
29
|
"""Order-preserving list that compares equal to sets/lists/tuples of same elements."""
|
|
30
30
|
|
|
31
31
|
def __eq__(self, other: object) -> bool:
|
{moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/calculation_worker.py
RENAMED
|
@@ -17,13 +17,13 @@ import re
|
|
|
17
17
|
import numpy as np
|
|
18
18
|
import sys
|
|
19
19
|
import subprocess
|
|
20
|
-
from typing import Any, Callable, Dict, Optional, Set, Tuple
|
|
20
|
+
from typing import Any, Callable, Dict, List, Optional, Set, Tuple
|
|
21
21
|
|
|
22
22
|
from PyQt6.QtCore import QObject, pyqtSignal, pyqtSlot
|
|
23
23
|
|
|
24
24
|
# RDKit
|
|
25
25
|
from rdkit import Chem
|
|
26
|
-
from rdkit.Chem import
|
|
26
|
+
from rdkit.Chem import rdDistGeom, rdForceFieldHelpers, rdGeometry
|
|
27
27
|
from rdkit.DistanceGeometry import DoTriangleSmoothing
|
|
28
28
|
|
|
29
29
|
from ..utils.constants import DEFAULT_BOND_LENGTH_ANGSTROM
|
|
@@ -235,14 +235,16 @@ def _iterative_optimize(
|
|
|
235
235
|
)
|
|
236
236
|
ff = None
|
|
237
237
|
if method == "UFF":
|
|
238
|
-
ff =
|
|
238
|
+
ff = rdForceFieldHelpers.UFFGetMoleculeForceField(
|
|
239
239
|
mol, confId=0, ignoreInterfragInteractions=ignore_interfrag
|
|
240
240
|
)
|
|
241
241
|
elif "MMFF94" in method:
|
|
242
242
|
mmff_variant = "MMFF94" if method == "MMFF94" else "MMFF94s"
|
|
243
|
-
props =
|
|
243
|
+
props = rdForceFieldHelpers.MMFFGetMoleculeProperties(
|
|
244
|
+
mol, mmffVariant=mmff_variant
|
|
245
|
+
)
|
|
244
246
|
if props:
|
|
245
|
-
ff =
|
|
247
|
+
ff = rdForceFieldHelpers.MMFFGetMoleculeForceField(
|
|
246
248
|
mol, props, confId=0, ignoreInterfragInteractions=ignore_interfrag
|
|
247
249
|
)
|
|
248
250
|
|
|
@@ -378,8 +380,10 @@ _DIRECT_WEDGE_TILT = math.radians(35.0)
|
|
|
378
380
|
|
|
379
381
|
|
|
380
382
|
def _rescale_2d_layout(
|
|
381
|
-
coords:
|
|
382
|
-
|
|
383
|
+
coords: List[Tuple[float, float, float]],
|
|
384
|
+
mol: Chem.Mol,
|
|
385
|
+
_safe_status: Callable[[str], None],
|
|
386
|
+
) -> List[Tuple[float, float, float]]:
|
|
383
387
|
"""Scale parsed 2D coordinates so the median bond is a chemically sane length."""
|
|
384
388
|
lengths = []
|
|
385
389
|
for bond in mol.GetBonds():
|
|
@@ -419,8 +423,12 @@ def _perform_direct_conversion(
|
|
|
419
423
|
options: Optional[Dict[str, Any]],
|
|
420
424
|
_check_halted: Callable[[], bool],
|
|
421
425
|
_safe_status: Callable[[str], None],
|
|
422
|
-
) ->
|
|
423
|
-
"""Direct 3D conversion using 2D coordinates and adding missing H without embedding.
|
|
426
|
+
) -> Chem.Mol:
|
|
427
|
+
"""Direct 3D conversion using 2D coordinates and adding missing H without embedding.
|
|
428
|
+
|
|
429
|
+
Returns the same molecule it was given: the conversion mutates ``mol`` in
|
|
430
|
+
place and never rebinds it, so the result is never None.
|
|
431
|
+
"""
|
|
424
432
|
parsed_coords, stereo_dirs = [], []
|
|
425
433
|
# Best-effort attempt to parse 2D coordinates from MOL block for direct conversion.
|
|
426
434
|
# We suppress AttributeError/RuntimeError if the block is malformed or RDKit fails internally.
|
|
@@ -724,10 +732,10 @@ print(ob_mol.write("mol"))
|
|
|
724
732
|
f"Subprocess crashed or failed. Error: {result.stderr.strip()}"
|
|
725
733
|
)
|
|
726
734
|
out_mol_block = result.stdout
|
|
727
|
-
except subprocess.TimeoutExpired:
|
|
728
|
-
raise RuntimeError("Open Babel make3D() timed out.")
|
|
735
|
+
except subprocess.TimeoutExpired as exc:
|
|
736
|
+
raise RuntimeError("Open Babel make3D() timed out.") from exc
|
|
729
737
|
except Exception as e:
|
|
730
|
-
raise RuntimeError(f"Open Babel isolated execution failed: {e}")
|
|
738
|
+
raise RuntimeError(f"Open Babel isolated execution failed: {e}") from e
|
|
731
739
|
|
|
732
740
|
rd_mol = Chem.MolFromMolBlock(out_mol_block, removeHs=False)
|
|
733
741
|
if not rd_mol:
|
|
@@ -786,7 +794,7 @@ print(ob_mol.write("mol"))
|
|
|
786
794
|
raise
|
|
787
795
|
except (AttributeError, RuntimeError, ValueError, TypeError) as e:
|
|
788
796
|
if mode == "obabel":
|
|
789
|
-
raise RuntimeError(f"Open Babel conversion failed: {e}")
|
|
797
|
+
raise RuntimeError(f"Open Babel conversion failed: {e}") from e
|
|
790
798
|
_safe_status(f"Open Babel failed: {e}. Falling back...")
|
|
791
799
|
return False
|
|
792
800
|
|
|
@@ -953,11 +961,15 @@ class CalculationWorker(QObject):
|
|
|
953
961
|
_safe_finished = helpers["finished"]
|
|
954
962
|
w_id = options.get("worker_id")
|
|
955
963
|
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
964
|
+
# rdkit's stub declares these EmbedParameters properties with bare
|
|
965
|
+
# `*args, **kwargs` and no annotations, so every assignment through them
|
|
966
|
+
# is reported as a type error. Unchained here so each one can carry the
|
|
967
|
+
# narrowest possible ignore.
|
|
968
|
+
params = rdDistGeom.ETKDGv2()
|
|
969
|
+
params.randomSeed = 42 # type: ignore[assignment]
|
|
970
|
+
params.useExpTorsionAnglePrefs = True # type: ignore[assignment]
|
|
971
|
+
params.useBasicKnowledge = True # type: ignore[assignment]
|
|
972
|
+
params.enforceChirality = True # type: ignore[assignment]
|
|
961
973
|
|
|
962
974
|
# Track existing/explicit stereo to restore after embedding
|
|
963
975
|
orig_stereo = []
|
|
@@ -980,22 +992,18 @@ class CalculationWorker(QObject):
|
|
|
980
992
|
|
|
981
993
|
conf_id = -1
|
|
982
994
|
with suppress_log(RuntimeError, ValueError):
|
|
983
|
-
conf_id =
|
|
995
|
+
conf_id = rdDistGeom.EmbedMolecule(mol, params)
|
|
984
996
|
|
|
985
997
|
# Fallback embedding strategies
|
|
986
998
|
if conf_id == -1:
|
|
987
999
|
with suppress_log(AttributeError, RuntimeError, ValueError, TypeError):
|
|
988
|
-
bm =
|
|
989
|
-
for
|
|
1000
|
+
bm = rdDistGeom.GetMoleculeBoundsMatrix(mol)
|
|
1001
|
+
for _b_idx, s, satoms in orig_stereo:
|
|
990
1002
|
if len(satoms) == 2:
|
|
991
1003
|
t = 3.0 if s == Chem.BondStereo.STEREOZ else 5.0
|
|
992
1004
|
bm[satoms[0]][satoms[1]] = bm[satoms[1]][satoms[0]] = t
|
|
993
1005
|
DoTriangleSmoothing(bm)
|
|
994
|
-
conf_id =
|
|
995
|
-
|
|
996
|
-
if conf_id == -1:
|
|
997
|
-
with suppress_log(AttributeError, RuntimeError, ValueError, TypeError):
|
|
998
|
-
conf_id = AllChem.EmbedMolecule(mol, AllChem.ETKDGv2(randomSeed=42))
|
|
1006
|
+
conf_id = rdDistGeom.EmbedMolecule(mol, bm, params)
|
|
999
1007
|
|
|
1000
1008
|
if conf_id == -1:
|
|
1001
1009
|
return False
|
|
@@ -13,13 +13,23 @@ DOI: 10.5281/zenodo.17268532
|
|
|
13
13
|
from __future__ import annotations
|
|
14
14
|
import logging
|
|
15
15
|
from ..utils.suppress_log import suppress_log
|
|
16
|
-
from typing import
|
|
16
|
+
from typing import (
|
|
17
|
+
Any,
|
|
18
|
+
Dict,
|
|
19
|
+
List,
|
|
20
|
+
Optional,
|
|
21
|
+
Sequence,
|
|
22
|
+
Set,
|
|
23
|
+
Tuple,
|
|
24
|
+
Union,
|
|
25
|
+
TYPE_CHECKING,
|
|
26
|
+
)
|
|
17
27
|
|
|
18
28
|
from PyQt6.QtCore import QThread, QTimer, QPoint
|
|
19
29
|
from PyQt6.QtGui import QAction, QColor
|
|
20
30
|
from PyQt6.QtWidgets import QMenu, QMessageBox, QWidget
|
|
21
31
|
from rdkit import Chem
|
|
22
|
-
from rdkit.Chem import
|
|
32
|
+
from rdkit.Chem import rdDepictor
|
|
23
33
|
|
|
24
34
|
from . import OBABEL_AVAILABLE
|
|
25
35
|
|
|
@@ -387,6 +397,11 @@ class ComputeManager:
|
|
|
387
397
|
"""
|
|
388
398
|
mol = self.host.view_3d_manager.current_mol
|
|
389
399
|
label = entry.get("label", method)
|
|
400
|
+
if mol is None:
|
|
401
|
+
self.host.update_status_message(
|
|
402
|
+
f"Optimization with {label} needs a 3D structure."
|
|
403
|
+
)
|
|
404
|
+
return
|
|
390
405
|
self.host.update_status_message(f"Optimizing 3D structure ({label})...")
|
|
391
406
|
try:
|
|
392
407
|
success = bool(entry["callback"](mol))
|
|
@@ -410,7 +425,7 @@ class ComputeManager:
|
|
|
410
425
|
self._refresh_ui_state()
|
|
411
426
|
self.host.edit_actions_manager.push_undo_state()
|
|
412
427
|
if self.host.view_3d_manager.plotter:
|
|
413
|
-
self.host.view_3d_manager.plotter.reset_camera()
|
|
428
|
+
self.host.view_3d_manager.plotter.reset_camera() # type: ignore[call-arg]
|
|
414
429
|
self.host.update_status_message(f"Process completed ({label}).")
|
|
415
430
|
|
|
416
431
|
def _prepare_rdkit_mol_for_conversion(self) -> Optional[Chem.Mol]:
|
|
@@ -439,7 +454,9 @@ class ComputeManager:
|
|
|
439
454
|
return None
|
|
440
455
|
return mol
|
|
441
456
|
|
|
442
|
-
def _handle_chemistry_problems(
|
|
457
|
+
def _handle_chemistry_problems(
|
|
458
|
+
self, mol: Chem.Mol, problems: Sequence[Any]
|
|
459
|
+
) -> None:
|
|
443
460
|
self.host.init_manager.scene.clear_all_problem_flags()
|
|
444
461
|
msg = f"Error: {len(problems)} chemistry problem(s) found (e.g., hypervalency). Fix the 2D layout before converting."
|
|
445
462
|
self.host.statusBar().showMessage(msg) # type: ignore[union-attr]
|
|
@@ -474,7 +491,7 @@ class ComputeManager:
|
|
|
474
491
|
# 3D generation; the 2D canvas keeps the user's own layout.
|
|
475
492
|
planar = Chem.Mol(stereo_mol)
|
|
476
493
|
planar.RemoveAllConformers()
|
|
477
|
-
|
|
494
|
+
rdDepictor.Compute2DCoords(planar)
|
|
478
495
|
return str(Chem.MolToMolBlock(planar, includeStereo=True))
|
|
479
496
|
except (RuntimeError, ValueError) as e:
|
|
480
497
|
logging.warning("E/Z-consistent 2D layout failed: %s", e)
|
|
@@ -556,7 +573,7 @@ class ComputeManager:
|
|
|
556
573
|
self._refresh_ui_state()
|
|
557
574
|
self.host.edit_actions_manager.push_undo_state()
|
|
558
575
|
if self.host.view_3d_manager.plotter:
|
|
559
|
-
self.host.view_3d_manager.plotter.reset_camera()
|
|
576
|
+
self.host.view_3d_manager.plotter.reset_camera() # type: ignore[call-arg]
|
|
560
577
|
|
|
561
578
|
# Record the successful optimization method from mol property or current setting
|
|
562
579
|
try:
|
|
@@ -28,7 +28,7 @@ from PyQt6.QtWidgets import (
|
|
|
28
28
|
QTableWidgetItem,
|
|
29
29
|
QVBoxLayout,
|
|
30
30
|
)
|
|
31
|
-
from rdkit.Chem import
|
|
31
|
+
from rdkit.Chem import rdForceFieldHelpers, rdMolTransforms
|
|
32
32
|
|
|
33
33
|
from .dialog_3d_picking_mixin import Dialog3DPickingMixin
|
|
34
34
|
|
|
@@ -378,7 +378,7 @@ class ConstrainedOptimizationDialog(Dialog3DPickingMixin, QDialog):
|
|
|
378
378
|
def remove_constraint(self) -> None:
|
|
379
379
|
"""Delete the selected constraint rows from the table."""
|
|
380
380
|
selected_rows = sorted(
|
|
381
|
-
|
|
381
|
+
{index.row() for index in self.constraint_table.selectedIndexes()},
|
|
382
382
|
reverse=True,
|
|
383
383
|
)
|
|
384
384
|
if not selected_rows:
|
|
@@ -511,8 +511,10 @@ class ConstrainedOptimizationDialog(Dialog3DPickingMixin, QDialog):
|
|
|
511
511
|
"optimize_intermolecular_interaction_rdkit", True
|
|
512
512
|
)
|
|
513
513
|
if ff_name.startswith("MMFF"):
|
|
514
|
-
props =
|
|
515
|
-
|
|
514
|
+
props = rdForceFieldHelpers.MMFFGetMoleculeProperties(
|
|
515
|
+
self.mol, mmffVariant=ff_name
|
|
516
|
+
)
|
|
517
|
+
ff = rdForceFieldHelpers.MMFFGetMoleculeForceField(
|
|
516
518
|
self.mol,
|
|
517
519
|
props,
|
|
518
520
|
confId=0,
|
|
@@ -522,7 +524,7 @@ class ConstrainedOptimizationDialog(Dialog3DPickingMixin, QDialog):
|
|
|
522
524
|
add_angle_constraint = ff.MMFFAddAngleConstraint
|
|
523
525
|
add_torsion_constraint = ff.MMFFAddTorsionConstraint
|
|
524
526
|
else: # UFF
|
|
525
|
-
ff =
|
|
527
|
+
ff = rdForceFieldHelpers.UFFGetMoleculeForceField(
|
|
526
528
|
self.mol, confId=0, ignoreInterfragInteractions=ignore_interfrag
|
|
527
529
|
)
|
|
528
530
|
add_dist_constraint = ff.UFFAddDistanceConstraint
|
{moleditpy_linux-4.8.2 → moleditpy_linux-4.8.3}/src/moleditpy_linux/ui/custom_interactor_style.py
RENAMED
|
@@ -923,7 +923,10 @@ class CustomInteractorStyle(vtkInteractorStyleTrackballCamera):
|
|
|
923
923
|
logging.debug("Suppressed non-critical error", exc_info=True)
|
|
924
924
|
|
|
925
925
|
def _compute_delta_rotation_matrix(
|
|
926
|
-
self,
|
|
926
|
+
self,
|
|
927
|
+
renderer: Any,
|
|
928
|
+
start_pos: Tuple[float, float],
|
|
929
|
+
current_pos: Tuple[float, float],
|
|
927
930
|
) -> Optional[np.ndarray]:
|
|
928
931
|
"""Compute 3D rotation matrix from screen mouse displacement (dx, dy)."""
|
|
929
932
|
try:
|