MoleditPy 2.8.0a2__tar.gz → 2.8.0a4__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-2.8.0a2 → moleditpy-2.8.0a4}/PKG-INFO +3 -2
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/pyproject.toml +3 -2
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/MoleditPy.egg-info/PKG-INFO +3 -2
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/MoleditPy.egg-info/requires.txt +6 -1
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/calculation_worker.py +41 -14
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/constants.py +1 -1
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/main_window_compute.py +4 -1
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/LICENSE +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/README.md +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/setup.cfg +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/MoleditPy.egg-info/SOURCES.txt +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/MoleditPy.egg-info/dependency_links.txt +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/MoleditPy.egg-info/entry_points.txt +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/MoleditPy.egg-info/top_level.txt +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/__init__.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/__main__.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/assets/file_icon.ico +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/assets/icon.icns +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/assets/icon.ico +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/assets/icon.png +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/main.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/__init__.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/about_dialog.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/align_plane_dialog.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/alignment_dialog.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/analysis_window.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/angle_dialog.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/atom_item.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/bond_item.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/bond_length_dialog.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/color_settings_dialog.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/constrained_optimization_dialog.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/custom_interactor_style.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/custom_qt_interactor.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/dialog3_d_picking_mixin.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/dihedral_dialog.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/main_window.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/main_window_app_state.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/main_window_dialog_manager.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/main_window_edit_3d.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/main_window_edit_actions.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/main_window_export.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/main_window_main_init.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/main_window_molecular_parsers.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/main_window_project_io.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/main_window_string_importers.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/main_window_ui_manager.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/main_window_view_3d.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/main_window_view_loaders.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/mirror_dialog.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/mol_geometry.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/molecular_data.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/molecule_scene.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/move_group_dialog.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/periodic_table_dialog.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/planarize_dialog.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/plugin_interface.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/plugin_manager.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/plugin_manager_window.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/settings_dialog.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/sip_isdeleted_safe.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/template_preview_item.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/template_preview_view.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/translation_dialog.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/user_template_dialog.py +0 -0
- {moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/zoomable_view.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: MoleditPy
|
|
3
|
-
Version: 2.8.
|
|
3
|
+
Version: 2.8.0a4
|
|
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
|
|
@@ -694,7 +694,8 @@ Requires-Python: <3.15,>=3.9
|
|
|
694
694
|
Description-Content-Type: text/markdown
|
|
695
695
|
License-File: LICENSE
|
|
696
696
|
Requires-Dist: numpy
|
|
697
|
-
Requires-Dist: pyqt6<6.
|
|
697
|
+
Requires-Dist: pyqt6<6.10; sys_platform == "darwin"
|
|
698
|
+
Requires-Dist: pyqt6<6.11; sys_platform != "darwin"
|
|
698
699
|
Requires-Dist: pyvista<0.48
|
|
699
700
|
Requires-Dist: pyvistaqt<0.12
|
|
700
701
|
Requires-Dist: rdkit<2025.10
|
|
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "MoleditPy"
|
|
7
7
|
|
|
8
|
-
version = "2.8.
|
|
8
|
+
version = "2.8.0a4"
|
|
9
9
|
|
|
10
10
|
license = {file = "LICENSE"}
|
|
11
11
|
|
|
@@ -34,7 +34,8 @@ classifiers = [
|
|
|
34
34
|
|
|
35
35
|
dependencies = [
|
|
36
36
|
"numpy",
|
|
37
|
-
"pyqt6 < 6.
|
|
37
|
+
"pyqt6 < 6.10; sys_platform == 'darwin'",
|
|
38
|
+
"pyqt6 < 6.11; sys_platform != 'darwin'",
|
|
38
39
|
"pyvista < 0.48",
|
|
39
40
|
"pyvistaqt < 0.12",
|
|
40
41
|
"rdkit < 2025.10",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: MoleditPy
|
|
3
|
-
Version: 2.8.
|
|
3
|
+
Version: 2.8.0a4
|
|
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
|
|
@@ -694,7 +694,8 @@ Requires-Python: <3.15,>=3.9
|
|
|
694
694
|
Description-Content-Type: text/markdown
|
|
695
695
|
License-File: LICENSE
|
|
696
696
|
Requires-Dist: numpy
|
|
697
|
-
Requires-Dist: pyqt6<6.
|
|
697
|
+
Requires-Dist: pyqt6<6.10; sys_platform == "darwin"
|
|
698
|
+
Requires-Dist: pyqt6<6.11; sys_platform != "darwin"
|
|
698
699
|
Requires-Dist: pyvista<0.48
|
|
699
700
|
Requires-Dist: pyvistaqt<0.12
|
|
700
701
|
Requires-Dist: rdkit<2025.10
|
|
@@ -21,21 +21,40 @@ from rdkit import Chem
|
|
|
21
21
|
from rdkit.Chem import AllChem, rdGeometry
|
|
22
22
|
from rdkit.DistanceGeometry import DoTriangleSmoothing
|
|
23
23
|
|
|
24
|
-
try:
|
|
24
|
+
try: # pragma: no cover
|
|
25
25
|
from . import OBABEL_AVAILABLE
|
|
26
|
-
except Exception:
|
|
26
|
+
except Exception: # pragma: no cover
|
|
27
27
|
from modules import OBABEL_AVAILABLE
|
|
28
28
|
# Only import pybel on demand — `moleditpy` itself doesn't expose `pybel`.
|
|
29
|
-
if OBABEL_AVAILABLE:
|
|
29
|
+
if OBABEL_AVAILABLE: # pragma: no cover
|
|
30
30
|
try:
|
|
31
31
|
import os
|
|
32
|
+
import glob
|
|
32
33
|
import openbabel
|
|
33
34
|
from openbabel import pybel
|
|
34
35
|
|
|
35
36
|
# The python wheel often misses setting up the data directory.
|
|
36
|
-
#
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
# Check multiple potential locations for BABEL_DATADIR.
|
|
38
|
+
ob_base = os.path.dirname(openbabel.__file__)
|
|
39
|
+
data_candidates = [
|
|
40
|
+
os.path.join(ob_base, "bin", "data"), # Typical for Windows wheel
|
|
41
|
+
os.path.join(ob_base, "share", "openbabel", "*") # Typical for macOS/Linux
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
found_datadir = None
|
|
45
|
+
for pattern in data_candidates:
|
|
46
|
+
matches = glob.glob(pattern)
|
|
47
|
+
for m in matches:
|
|
48
|
+
if os.path.isdir(m):
|
|
49
|
+
found_datadir = m
|
|
50
|
+
break
|
|
51
|
+
if found_datadir:
|
|
52
|
+
break
|
|
53
|
+
|
|
54
|
+
if found_datadir:
|
|
55
|
+
os.environ["BABEL_DATADIR"] = found_datadir
|
|
56
|
+
|
|
57
|
+
os.environ["BABEL_LIBDIR"] = ob_base
|
|
39
58
|
except Exception:
|
|
40
59
|
# If import fails here, disable OBABEL locally; avoid raising
|
|
41
60
|
pybel = None
|
|
@@ -43,7 +62,7 @@ if OBABEL_AVAILABLE:
|
|
|
43
62
|
print(
|
|
44
63
|
"Warning: openbabel.pybel not available. Open Babel fallback and OBabel-based options will be disabled."
|
|
45
64
|
)
|
|
46
|
-
else:
|
|
65
|
+
else: # pragma: no cover
|
|
47
66
|
pybel = None
|
|
48
67
|
|
|
49
68
|
|
|
@@ -172,7 +191,7 @@ def _adjust_collision_avoidance(rd_mol, check_halted_cb, safe_status_cb):
|
|
|
172
191
|
safe_status_cb("Collision avoidance completed.")
|
|
173
192
|
except WorkerHaltError:
|
|
174
193
|
raise
|
|
175
|
-
except Exception as e:
|
|
194
|
+
except Exception as e: # pragma: no cover
|
|
176
195
|
import traceback
|
|
177
196
|
traceback.print_exc()
|
|
178
197
|
safe_status_cb(f"Collision avoidance warning: {e}")
|
|
@@ -276,11 +295,11 @@ class CalculationWorker(QObject):
|
|
|
276
295
|
error = pyqtSignal(object)
|
|
277
296
|
start_work = pyqtSignal(str, object)
|
|
278
297
|
|
|
279
|
-
def __init__(self, parent=None):
|
|
298
|
+
def __init__(self, parent=None): # pragma: no cover
|
|
280
299
|
super().__init__(parent)
|
|
281
300
|
try:
|
|
282
301
|
self.start_work.connect(self.run_calculation)
|
|
283
|
-
except Exception:
|
|
302
|
+
except Exception:
|
|
284
303
|
import traceback
|
|
285
304
|
traceback.print_exc()
|
|
286
305
|
|
|
@@ -308,7 +327,7 @@ class CalculationWorker(QObject):
|
|
|
308
327
|
return False
|
|
309
328
|
|
|
310
329
|
# Safe-emission helpers: do nothing if this worker has been halted.
|
|
311
|
-
def _safe_status(msg):
|
|
330
|
+
def _safe_status(msg): # pragma: no cover
|
|
312
331
|
try:
|
|
313
332
|
if _check_halted():
|
|
314
333
|
raise WorkerHaltError("Halted")
|
|
@@ -374,13 +393,13 @@ class CalculationWorker(QObject):
|
|
|
374
393
|
worker_id = None
|
|
375
394
|
|
|
376
395
|
_warned_no_worker_id = False
|
|
377
|
-
if worker_id is None:
|
|
396
|
+
if worker_id is None: # pragma: no cover
|
|
378
397
|
try:
|
|
379
398
|
# best-effort, swallow any errors (signals may not be connected)
|
|
380
399
|
self.status_update.emit(
|
|
381
400
|
"Warning: worker started without 'worker_id'; will listen for global halt signals."
|
|
382
401
|
)
|
|
383
|
-
except Exception:
|
|
402
|
+
except Exception:
|
|
384
403
|
import traceback
|
|
385
404
|
traceback.print_exc()
|
|
386
405
|
_warned_no_worker_id = True
|
|
@@ -486,8 +505,16 @@ class CalculationWorker(QObject):
|
|
|
486
505
|
method_key = "GHEMICAL"
|
|
487
506
|
|
|
488
507
|
if backend == "OBABEL":
|
|
508
|
+
try:
|
|
509
|
+
mol.SetProp("_pme_optimization_method", opt_method)
|
|
510
|
+
except Exception:
|
|
511
|
+
pass
|
|
489
512
|
opt_success = _iterative_optimize_obabel(mol, method_key, _check_halted, _safe_status)
|
|
490
513
|
else:
|
|
514
|
+
try:
|
|
515
|
+
mol.SetProp("_pme_optimization_method", opt_method)
|
|
516
|
+
except Exception:
|
|
517
|
+
pass
|
|
491
518
|
opt_success = _iterative_optimize(mol, method_key, _check_halted, _safe_status)
|
|
492
519
|
|
|
493
520
|
if not opt_success:
|
|
@@ -1081,7 +1108,7 @@ class CalculationWorker(QObject):
|
|
|
1081
1108
|
conf_id = AllChem.EmbedMolecule(mol, basic_params)
|
|
1082
1109
|
else:
|
|
1083
1110
|
conf_id = -1
|
|
1084
|
-
except Exception:
|
|
1111
|
+
except Exception: # pragma: no cover
|
|
1085
1112
|
import traceback
|
|
1086
1113
|
traceback.print_exc()
|
|
1087
1114
|
"""
|
|
@@ -1119,7 +1119,10 @@ class MainWindowCompute(object):
|
|
|
1119
1119
|
import traceback
|
|
1120
1120
|
traceback.print_exc()
|
|
1121
1121
|
|
|
1122
|
-
|
|
1122
|
+
if self.last_successful_optimization_method:
|
|
1123
|
+
self.statusBar().showMessage(f"3D calculation ({self.last_successful_optimization_method}) successful.")
|
|
1124
|
+
else:
|
|
1125
|
+
self.statusBar().showMessage("3D calculation successful.")
|
|
1123
1126
|
self.convert_button.setEnabled(True)
|
|
1124
1127
|
# Restore button text/handlers in case they were changed to Halt
|
|
1125
1128
|
try:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/constrained_optimization_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/main_window_molecular_parsers.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy-2.8.0a2 → moleditpy-2.8.0a4}/src/moleditpy/modules/main_window_string_importers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|