MoleditPy-linux 4.11.4__tar.gz → 4.12.0__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.11.4 → moleditpy_linux-4.12.0}/PKG-INFO +1 -1
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/pyproject.toml +1 -1
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/MoleditPy_linux.egg-info/PKG-INFO +1 -1
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/core/molecular_data.py +242 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/core/stereo_check.py +69 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/chirality_warning_dialog.py +37 -10
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/compute_logic.py +4 -1
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/io_logic.py +0 -3
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/view_3d_logic.py +11 -8
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/LICENSE +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/README.md +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/setup.cfg +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/MoleditPy_linux.egg-info/SOURCES.txt +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/MoleditPy_linux.egg-info/dependency_links.txt +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/MoleditPy_linux.egg-info/entry_points.txt +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/MoleditPy_linux.egg-info/requires.txt +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/MoleditPy_linux.egg-info/top_level.txt +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/__init__.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/__main__.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/assets/file_icon.ico +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/assets/icon.icns +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/assets/icon.ico +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/assets/icon.png +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/core/__init__.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/core/mol_geometry.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/main.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/plugins/__init__.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/plugins/plugin_interface.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/plugins/plugin_manager.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/plugins/plugin_manager_window.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/__init__.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/about_dialog.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/align_plane_dialog.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/alignment_dialog.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/analysis_window.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/angle_dialog.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/app_state.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/atom_item.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/atom_picking.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/base_picking_dialog.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/bond_item.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/bond_length_dialog.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/calculation_worker.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/chain_mixin.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/color_settings_dialog.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/constrained_optimization_dialog.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/custom_interactor_style.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/custom_qt_interactor.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/dialog_3d_picking_mixin.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/dialog_logic.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/dihedral_dialog.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/edit_3d_logic.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/edit_actions_logic.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/export_logic.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/geometry_base_dialog.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/main_window.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/main_window_init.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/mirror_dialog.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/molecular_scene_handler.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/molecule_scene.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/move_dialog_mixin.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/move_group_dialog.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/move_selected_atoms_dialog.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/periodic_table_dialog.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/planarize_dialog.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/plugin_menu_manager.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/preview_molecule.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/sdf_record_dialog.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/settings_dialog.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/settings_tabs/__init__.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/settings_tabs/settings_2d_cleanup_tab.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/settings_tabs/settings_2d_tab.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/settings_tabs/settings_3d_tabs.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/settings_tabs/settings_labels_tab.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/settings_tabs/settings_other_tab.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/settings_tabs/settings_tab_base.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/string_importers.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/template_preview_item.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/template_preview_view.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/translation_dialog.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/ui_manager.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/user_template_dialog.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/zoomable_view.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/utils/__init__.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/utils/constants.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/utils/default_settings.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/utils/finite_float.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/utils/hit_radius.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/utils/label_style.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/utils/sdf_records.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/utils/sip_isdeleted_safe.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/utils/suppress_log.py +0 -0
- {moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/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.
|
|
3
|
+
Version: 4.12.0
|
|
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.
|
|
3
|
+
Version: 4.12.0
|
|
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
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/core/molecular_data.py
RENAMED
|
@@ -12,6 +12,7 @@ DOI: 10.5281/zenodo.17268532
|
|
|
12
12
|
|
|
13
13
|
from __future__ import annotations
|
|
14
14
|
import logging
|
|
15
|
+
import math
|
|
15
16
|
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
16
17
|
from rdkit import Chem
|
|
17
18
|
from rdkit.Chem import rdCIPLabeler
|
|
@@ -150,6 +151,245 @@ def align_ez_to_cip(mol: Chem.Mol, wanted: Dict[int, str]) -> None:
|
|
|
150
151
|
bond.SetStereo(flipped[bond.GetStereo()])
|
|
151
152
|
|
|
152
153
|
|
|
154
|
+
_WEDGE_Z = {Chem.BondDir.BEGINWEDGE: 1.0, Chem.BondDir.BEGINDASH: -1.0}
|
|
155
|
+
|
|
156
|
+
# How far past a straight line the two bonds without a wedge may open and
|
|
157
|
+
# still count as a T-shape rather than a fan the wedge sits inside.
|
|
158
|
+
_T_SHAPE_TOLERANCE_DEG = 5.0
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def _tag_from_points(
|
|
162
|
+
mol: Chem.Mol,
|
|
163
|
+
center: int,
|
|
164
|
+
points: Dict[int, Tuple[float, float, float]],
|
|
165
|
+
virtual: Optional[Tuple[float, float, float]] = None,
|
|
166
|
+
) -> Chem.ChiralType:
|
|
167
|
+
"""Chiral tag of *center* with its neighbors at *points* (center-relative).
|
|
168
|
+
|
|
169
|
+
*virtual* is the position of an implicit H or lone pair. The center is
|
|
170
|
+
placed at the centroid of the four positions, inside the tetrahedron, so
|
|
171
|
+
any three neighbor vectors are independent.
|
|
172
|
+
"""
|
|
173
|
+
corners = list(points.values()) + ([virtual] if virtual is not None else [])
|
|
174
|
+
centroid = tuple(sum(p[k] for p in corners) / len(corners) for k in range(3))
|
|
175
|
+
probe = Chem.Mol(mol)
|
|
176
|
+
conf = Chem.Conformer(probe.GetNumAtoms())
|
|
177
|
+
conf.Set3D(True)
|
|
178
|
+
for idx, pos in points.items():
|
|
179
|
+
conf.SetAtomPosition(idx, pos)
|
|
180
|
+
conf.SetAtomPosition(center, centroid)
|
|
181
|
+
probe.RemoveAllConformers()
|
|
182
|
+
conf_id = probe.AddConformer(conf, assignId=True)
|
|
183
|
+
Chem.AssignAtomChiralTagsFromStructure(probe, confId=conf_id)
|
|
184
|
+
return probe.GetAtomWithIdx(center).GetChiralTag()
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def _largest_gap_deg(directions: List[Tuple[float, float]]) -> float:
|
|
188
|
+
"""Largest angle between angularly adjacent 2D directions, in degrees."""
|
|
189
|
+
angles = sorted(math.degrees(math.atan2(dy, dx)) % 360.0 for dx, dy in directions)
|
|
190
|
+
gaps = [b - a for a, b in zip(angles, angles[1:])]
|
|
191
|
+
gaps.append(360.0 - angles[-1] + angles[0])
|
|
192
|
+
return max(gaps)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def wedge_reading(mol: Chem.Mol, center: int) -> Optional[Chem.ChiralType]:
|
|
196
|
+
"""Chiral tag the wedges/hashes starting at *center* specify, or None.
|
|
197
|
+
|
|
198
|
+
Reads the drawing the way a chemist does: plain bonds in the paper plane,
|
|
199
|
+
a wedge toward the viewer, a hash away. With three drawn neighbors the
|
|
200
|
+
implicit H (or lone pair) points opposite the wedges. With four, each
|
|
201
|
+
stereo bond is read in turn as the one out of the plane; the reading
|
|
202
|
+
counts only when they all agree.
|
|
203
|
+
|
|
204
|
+
None means the drawing does not decide: no stereo bond starts here, a
|
|
205
|
+
wedge and a hash cancel on a three-neighbor center, the wedge sits inside
|
|
206
|
+
a fan of under 180 degrees, or the stereo bonds of a four-neighbor center
|
|
207
|
+
contradict each other (a wedge and a hash on opposite bonds).
|
|
208
|
+
"""
|
|
209
|
+
atom = mol.GetAtomWithIdx(center)
|
|
210
|
+
if atom.GetDegree() not in (3, 4) or mol.GetNumConformers() == 0:
|
|
211
|
+
return None
|
|
212
|
+
conf = mol.GetConformer()
|
|
213
|
+
origin = conf.GetAtomPosition(center)
|
|
214
|
+
directions: Dict[int, Tuple[float, float]] = {}
|
|
215
|
+
lift: Dict[int, float] = {}
|
|
216
|
+
for bond in atom.GetBonds():
|
|
217
|
+
nbr = bond.GetOtherAtomIdx(center)
|
|
218
|
+
pos = conf.GetAtomPosition(nbr)
|
|
219
|
+
dx, dy = pos.x - origin.x, pos.y - origin.y
|
|
220
|
+
length = math.hypot(dx, dy)
|
|
221
|
+
if length < 1e-6:
|
|
222
|
+
return None
|
|
223
|
+
directions[nbr] = (dx / length, dy / length)
|
|
224
|
+
lift[nbr] = (
|
|
225
|
+
_WEDGE_Z.get(bond.GetBondDir(), 0.0)
|
|
226
|
+
if bond.GetBeginAtomIdx() == center
|
|
227
|
+
else 0.0
|
|
228
|
+
)
|
|
229
|
+
stereo_nbrs = [nbr for nbr, z in lift.items() if z]
|
|
230
|
+
if not stereo_nbrs:
|
|
231
|
+
return None
|
|
232
|
+
flat = {nbr: (dx, dy, 0.0) for nbr, (dx, dy) in directions.items()}
|
|
233
|
+
|
|
234
|
+
if len(directions) == 3:
|
|
235
|
+
net = sum(lift.values())
|
|
236
|
+
if not net:
|
|
237
|
+
return None
|
|
238
|
+
if _largest_gap_deg(list(directions.values())) > 180.0 + _T_SHAPE_TOLERANCE_DEG:
|
|
239
|
+
return None
|
|
240
|
+
return _tag_from_points(mol, center, flat, (0.0, 0.0, -math.copysign(1.0, net)))
|
|
241
|
+
|
|
242
|
+
readings = set()
|
|
243
|
+
for nbr in stereo_nbrs:
|
|
244
|
+
points = dict(flat)
|
|
245
|
+
points[nbr] = (0.0, 0.0, lift[nbr])
|
|
246
|
+
readings.add(_tag_from_points(mol, center, points))
|
|
247
|
+
return readings.pop() if len(readings) == 1 else None
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def _bond_states(mol: Chem.Mol, indices: List[int]) -> List[Tuple[int, int, Any]]:
|
|
251
|
+
"""Begin, end and direction of the bonds at *indices*."""
|
|
252
|
+
return [
|
|
253
|
+
(
|
|
254
|
+
mol.GetBondWithIdx(i).GetBeginAtomIdx(),
|
|
255
|
+
mol.GetBondWithIdx(i).GetEndAtomIdx(),
|
|
256
|
+
mol.GetBondWithIdx(i).GetBondDir(),
|
|
257
|
+
)
|
|
258
|
+
for i in indices
|
|
259
|
+
]
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def _rdkit_tags(mol: Chem.Mol) -> List[Chem.ChiralType]:
|
|
263
|
+
"""Chiral tag RDKit's wedge perception gives each atom of *mol*."""
|
|
264
|
+
probe = Chem.Mol(mol)
|
|
265
|
+
for atom in probe.GetAtoms():
|
|
266
|
+
atom.SetChiralTag(Chem.ChiralType.CHI_UNSPECIFIED)
|
|
267
|
+
Chem.AssignChiralTypesFromBondDirs(probe)
|
|
268
|
+
return [atom.GetChiralTag() for atom in probe.GetAtoms()]
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def _clear_own_wedges(mol: Chem.Mol, centers: Dict[int, Chem.ChiralType]) -> None:
|
|
272
|
+
"""Remove the wedges/hashes that start at *centers*."""
|
|
273
|
+
for center in centers:
|
|
274
|
+
for bond in mol.GetAtomWithIdx(center).GetBonds():
|
|
275
|
+
if bond.GetBeginAtomIdx() == center and bond.GetBondDir() in _WEDGE_Z:
|
|
276
|
+
bond.SetBondDir(Chem.BondDir.NONE)
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
def _rdkit_rewedge(mol: Chem.Mol, fixes: Dict[int, Chem.ChiralType]) -> None:
|
|
280
|
+
"""Let RDKit wedge each fixed center for its wanted tag (may reverse bonds)."""
|
|
281
|
+
_clear_own_wedges(mol, fixes)
|
|
282
|
+
for center, tag in fixes.items():
|
|
283
|
+
mol.GetAtomWithIdx(center).SetChiralTag(tag)
|
|
284
|
+
Chem.WedgeMolBonds(mol, mol.GetConformer())
|
|
285
|
+
for center in fixes:
|
|
286
|
+
mol.GetAtomWithIdx(center).SetChiralTag(Chem.ChiralType.CHI_UNSPECIFIED)
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
def _pick_wedges(mol: Chem.Mol, fixes: Dict[int, Chem.ChiralType]) -> None:
|
|
290
|
+
"""Wedge or hash one free bond per fixed center so it reads its wanted tag.
|
|
291
|
+
|
|
292
|
+
A candidate counts only when RDKit and wedge_reading() agree on it.
|
|
293
|
+
"""
|
|
294
|
+
for center, tag in fixes.items():
|
|
295
|
+
for bond in mol.GetAtomWithIdx(center).GetBonds():
|
|
296
|
+
if (
|
|
297
|
+
bond.GetBeginAtomIdx() != center
|
|
298
|
+
or bond.GetBondDir() != Chem.BondDir.NONE
|
|
299
|
+
or bond.GetBondType() != Chem.BondType.SINGLE
|
|
300
|
+
):
|
|
301
|
+
continue
|
|
302
|
+
for direction in _WEDGE_Z:
|
|
303
|
+
bond.SetBondDir(direction)
|
|
304
|
+
if (
|
|
305
|
+
_rdkit_tags(mol)[center] == tag
|
|
306
|
+
and wedge_reading(mol, center) == tag
|
|
307
|
+
):
|
|
308
|
+
break
|
|
309
|
+
bond.SetBondDir(Chem.BondDir.NONE)
|
|
310
|
+
else:
|
|
311
|
+
continue
|
|
312
|
+
break
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
def resolve_wedge_chirality(mol: Chem.Mol) -> None:
|
|
316
|
+
"""Re-wedge stereocenters whose drawn wedges RDKit reads differently.
|
|
317
|
+
|
|
318
|
+
RDKit's wedge perception is unstable on some unambiguous drawings: with
|
|
319
|
+
the two plain bonds of a three-neighbor center drawn in a straight line
|
|
320
|
+
(a T-shape, which the editor's angle snapping produces), it reports
|
|
321
|
+
"ambiguous stereochemistry" or inverts the center, while the same drawing
|
|
322
|
+
bent by a few degrees reads correctly. Where wedge_reading() gives a
|
|
323
|
+
definite answer that RDKit's perception does not reproduce, the wedges at
|
|
324
|
+
that center are replaced by ones RDKit picks for the intended
|
|
325
|
+
configuration on the same coordinates (or, where RDKit declines, a wedge
|
|
326
|
+
or hash on a free bond of the center that both readings agree on), so
|
|
327
|
+
every later reader (MOL block, 3D embedding, stereo check) gets the drawn
|
|
328
|
+
isomer. Nothing is changed unless every other stereocenter and every
|
|
329
|
+
bond away from the fixed centers stays exactly as drawn.
|
|
330
|
+
"""
|
|
331
|
+
if mol.GetNumConformers() == 0:
|
|
332
|
+
return
|
|
333
|
+
centers = sorted(
|
|
334
|
+
{b.GetBeginAtomIdx() for b in mol.GetBonds() if b.GetBondDir() in _WEDGE_Z}
|
|
335
|
+
)
|
|
336
|
+
if not centers:
|
|
337
|
+
return
|
|
338
|
+
try:
|
|
339
|
+
read = _rdkit_tags(mol)
|
|
340
|
+
fixes: Dict[int, Chem.ChiralType] = {}
|
|
341
|
+
for center in centers:
|
|
342
|
+
wanted = wedge_reading(mol, center)
|
|
343
|
+
if wanted is not None and wanted != read[center]:
|
|
344
|
+
fixes[center] = wanted
|
|
345
|
+
if not fixes:
|
|
346
|
+
return
|
|
347
|
+
|
|
348
|
+
# Bonds the re-wedge must not touch: everything away from the fixed
|
|
349
|
+
# centers, and any wedge/hash an adjacent center draws onto a bond it
|
|
350
|
+
# shares with a fixed center.
|
|
351
|
+
protected = [
|
|
352
|
+
b.GetIdx()
|
|
353
|
+
for b in mol.GetBonds()
|
|
354
|
+
if b.GetBeginAtomIdx() not in fixes
|
|
355
|
+
and (b.GetEndAtomIdx() not in fixes or b.GetBondDir() in _WEDGE_Z)
|
|
356
|
+
]
|
|
357
|
+
before = _bond_states(mol, protected)
|
|
358
|
+
expected = [fixes.get(i, tag) for i, tag in enumerate(read)]
|
|
359
|
+
|
|
360
|
+
def holds(trial: Chem.Mol) -> bool:
|
|
361
|
+
"""Fixed centers read right; every other center and bond is as drawn."""
|
|
362
|
+
return (
|
|
363
|
+
_bond_states(trial, protected) == before
|
|
364
|
+
and _rdkit_tags(trial) == expected
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
# WedgeMolBonds may reverse bonds, which cannot be undone, so try it
|
|
368
|
+
# on a copy and touch the real molecule only once it holds.
|
|
369
|
+
trial = Chem.Mol(mol)
|
|
370
|
+
_rdkit_rewedge(trial, fixes)
|
|
371
|
+
if holds(trial):
|
|
372
|
+
_rdkit_rewedge(mol, fixes)
|
|
373
|
+
return
|
|
374
|
+
# WedgeMolBonds declines some centers, e.g. a T-shape whose one
|
|
375
|
+
# unambiguous bond already carries a neighbor's hash. Try each free
|
|
376
|
+
# bond of the center instead; this never reverses a bond.
|
|
377
|
+
trial = Chem.Mol(mol)
|
|
378
|
+
_clear_own_wedges(trial, fixes)
|
|
379
|
+
_pick_wedges(trial, fixes)
|
|
380
|
+
if holds(trial):
|
|
381
|
+
for center in fixes:
|
|
382
|
+
for bond in mol.GetAtomWithIdx(center).GetBonds():
|
|
383
|
+
if bond.GetBeginAtomIdx() == center:
|
|
384
|
+
bond.SetBondDir(
|
|
385
|
+
trial.GetBondWithIdx(bond.GetIdx()).GetBondDir()
|
|
386
|
+
)
|
|
387
|
+
return
|
|
388
|
+
logging.debug("Re-wedging stereocenters %s did not hold", sorted(fixes))
|
|
389
|
+
except (RuntimeError, ValueError) as e:
|
|
390
|
+
logging.warning("Resolving wedge stereochemistry failed: %s", e)
|
|
391
|
+
|
|
392
|
+
|
|
153
393
|
class MolecularData:
|
|
154
394
|
"""In-memory graph of atoms and bonds, independent of any UI framework."""
|
|
155
395
|
|
|
@@ -449,6 +689,8 @@ class MolecularData:
|
|
|
449
689
|
).get("type") not in (1, 2):
|
|
450
690
|
adjacent.SetBondDir(Chem.BondDir.NONE)
|
|
451
691
|
|
|
692
|
+
resolve_wedge_chirality(final_mol)
|
|
693
|
+
|
|
452
694
|
# The labels are CIP E/Z; the neighbors picked above are not always
|
|
453
695
|
# the CIP-higher ones.
|
|
454
696
|
align_ez_to_cip(final_mol, ez_wanted)
|
|
@@ -113,6 +113,75 @@ def find_chirality_mismatches(
|
|
|
113
113
|
]
|
|
114
114
|
|
|
115
115
|
|
|
116
|
+
def ambiguous_wedge_centers(data: MolecularData) -> List[int]:
|
|
117
|
+
"""Atom IDs of stereocenters whose wedges/hashes specify no configuration.
|
|
118
|
+
|
|
119
|
+
These are drawings RDKit rejects as ambiguous (for example a wedge and a
|
|
120
|
+
hash on opposite bonds), so the 3D structure gets an arbitrary
|
|
121
|
+
configuration there. Atoms that are not stereocenters are not reported.
|
|
122
|
+
"""
|
|
123
|
+
if not any(bond.get("stereo") in (1, 2) for bond in data.bonds.values()):
|
|
124
|
+
return []
|
|
125
|
+
mol = data.to_rdkit_mol(use_2d_stereo=False)
|
|
126
|
+
if mol is None:
|
|
127
|
+
return []
|
|
128
|
+
probe = Chem.Mol(mol)
|
|
129
|
+
Chem.AssignChiralTypesFromBondDirs(probe)
|
|
130
|
+
centers = {
|
|
131
|
+
bond.GetBeginAtomIdx()
|
|
132
|
+
for bond in mol.GetBonds()
|
|
133
|
+
if bond.GetBondDir() in (Chem.BondDir.BEGINWEDGE, Chem.BondDir.BEGINDASH)
|
|
134
|
+
}
|
|
135
|
+
found: List[int] = []
|
|
136
|
+
for idx in sorted(centers):
|
|
137
|
+
atom = probe.GetAtomWithIdx(idx)
|
|
138
|
+
if atom.GetChiralTag() != Chem.ChiralType.CHI_UNSPECIFIED:
|
|
139
|
+
continue
|
|
140
|
+
# A stereocenter keeps an arbitrary tag through perception.
|
|
141
|
+
trial = Chem.Mol(mol)
|
|
142
|
+
trial.GetAtomWithIdx(idx).SetChiralTag(Chem.ChiralType.CHI_TETRAHEDRAL_CW)
|
|
143
|
+
Chem.AssignStereochemistry(trial, cleanIt=True, force=True)
|
|
144
|
+
trial_atom = trial.GetAtomWithIdx(idx)
|
|
145
|
+
if trial_atom.GetChiralTag() != Chem.ChiralType.CHI_UNSPECIFIED and (
|
|
146
|
+
trial_atom.HasProp("_original_atom_id")
|
|
147
|
+
):
|
|
148
|
+
found.append(trial_atom.GetIntProp("_original_atom_id"))
|
|
149
|
+
return found
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def find_ambiguous_centers(
|
|
153
|
+
data: MolecularData, mol_3d: Chem.Mol
|
|
154
|
+
) -> List[ChiralityMismatch]:
|
|
155
|
+
"""Ambiguously wedged stereocenters, with ``drawn`` set to "ambiguous".
|
|
156
|
+
|
|
157
|
+
``actual`` is the configuration the 3D structure happened to get.
|
|
158
|
+
"""
|
|
159
|
+
try:
|
|
160
|
+
atom_ids = ambiguous_wedge_centers(data)
|
|
161
|
+
if not atom_ids:
|
|
162
|
+
return []
|
|
163
|
+
actual = actual_chirality(mol_3d)
|
|
164
|
+
except (RuntimeError, ValueError) as e:
|
|
165
|
+
logging.warning("Ambiguous wedge check failed: %s", e)
|
|
166
|
+
return []
|
|
167
|
+
index_of = {
|
|
168
|
+
atom.GetIntProp("_original_atom_id"): atom.GetIdx()
|
|
169
|
+
for atom in mol_3d.GetAtoms()
|
|
170
|
+
if atom.HasProp("_original_atom_id")
|
|
171
|
+
}
|
|
172
|
+
return [
|
|
173
|
+
ChiralityMismatch(
|
|
174
|
+
atom_id=atom_id,
|
|
175
|
+
symbol=str(data.atoms[atom_id]["symbol"]),
|
|
176
|
+
rdkit_index=index_of.get(atom_id),
|
|
177
|
+
drawn="ambiguous",
|
|
178
|
+
actual=actual.get(atom_id),
|
|
179
|
+
)
|
|
180
|
+
for atom_id in atom_ids
|
|
181
|
+
if atom_id in data.atoms
|
|
182
|
+
]
|
|
183
|
+
|
|
184
|
+
|
|
116
185
|
def _bond_cip_by_atom_ids(
|
|
117
186
|
mol: Chem.Mol,
|
|
118
187
|
) -> Dict[FrozenSet[int], Tuple[int, str]]:
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/chirality_warning_dialog.py
RENAMED
|
@@ -88,16 +88,47 @@ class ChiralityWarningDialog(QDialog):
|
|
|
88
88
|
)
|
|
89
89
|
return rows
|
|
90
90
|
|
|
91
|
+
def _summary_text(self, row_count: int, total: int) -> str:
|
|
92
|
+
"""Rich-text summary: wrong elements, then ambiguously drawn centers."""
|
|
93
|
+
ambiguous = sum(1 for m in self.mismatches if m.drawn == "ambiguous")
|
|
94
|
+
wrong = row_count - ambiguous
|
|
95
|
+
parts = []
|
|
96
|
+
if wrong:
|
|
97
|
+
parts.append(
|
|
98
|
+
f"<b>The 3D structure is wrong.</b><br>"
|
|
99
|
+
f"{wrong} of {total} stereo element(s) drawn in 2D (R/S centers, "
|
|
100
|
+
f"E/Z double bonds) have a different configuration in 3D."
|
|
101
|
+
)
|
|
102
|
+
if ambiguous:
|
|
103
|
+
parts.append(
|
|
104
|
+
f"<b>{ambiguous} stereocenter(s) are drawn ambiguously</b> "
|
|
105
|
+
f"(for example a wedge and a hash on opposite bonds), so the "
|
|
106
|
+
f"wedges do not specify a configuration and the 3D one shown is "
|
|
107
|
+
f"arbitrary. Redraw them with one wedge or hash, or with the "
|
|
108
|
+
f"wedge and hash on adjacent bonds."
|
|
109
|
+
)
|
|
110
|
+
return "<br><br>".join(parts)
|
|
111
|
+
|
|
112
|
+
def _hint_text(self, row_count: int) -> str:
|
|
113
|
+
"""What to do next; flipping applies only to wrong, not ambiguous, rows."""
|
|
114
|
+
ambiguous = sum(1 for m in self.mismatches if m.drawn == "ambiguous")
|
|
115
|
+
labels = (
|
|
116
|
+
"While this window is open, the 3D view shows chiral and E/Z labels: "
|
|
117
|
+
"listed ones in red, the others in the usual color."
|
|
118
|
+
)
|
|
119
|
+
if row_count == ambiguous:
|
|
120
|
+
return labels
|
|
121
|
+
flip = "Please flip the wrong ones manually in the 3D structure."
|
|
122
|
+
if not ambiguous:
|
|
123
|
+
flip = "Please flip these manually in the 3D structure."
|
|
124
|
+
return f"{flip} {labels}"
|
|
125
|
+
|
|
91
126
|
def _build_ui(self, total: int) -> None:
|
|
92
127
|
"""Lay out the summary, the per-item table and the close button."""
|
|
93
128
|
layout = QVBoxLayout(self)
|
|
94
129
|
|
|
95
130
|
rows = self._rows()
|
|
96
|
-
summary = QLabel(
|
|
97
|
-
f"<b>The 3D structure is wrong.</b><br>"
|
|
98
|
-
f"{len(rows)} of {total} stereo element(s) drawn in 2D (R/S centers, "
|
|
99
|
-
f"E/Z double bonds) have a different configuration in 3D."
|
|
100
|
-
)
|
|
131
|
+
summary = QLabel(self._summary_text(len(rows), total))
|
|
101
132
|
summary.setWordWrap(True)
|
|
102
133
|
layout.addWidget(summary)
|
|
103
134
|
|
|
@@ -115,11 +146,7 @@ class ChiralityWarningDialog(QDialog):
|
|
|
115
146
|
header.setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
|
|
116
147
|
layout.addWidget(table)
|
|
117
148
|
|
|
118
|
-
hint = QLabel(
|
|
119
|
-
"Please flip these manually in the 3D structure. While this window "
|
|
120
|
-
"is open, the 3D view shows chiral and E/Z labels: wrong ones in "
|
|
121
|
-
"red, correct ones in the usual color."
|
|
122
|
-
)
|
|
149
|
+
hint = QLabel(self._hint_text(len(rows)))
|
|
123
150
|
hint.setWordWrap(True)
|
|
124
151
|
layout.addWidget(hint)
|
|
125
152
|
|
|
@@ -41,6 +41,7 @@ from ..core.mol_geometry import (
|
|
|
41
41
|
from ..core.stereo_check import (
|
|
42
42
|
drawn_chirality,
|
|
43
43
|
drawn_ez,
|
|
44
|
+
find_ambiguous_centers,
|
|
44
45
|
find_chirality_mismatches,
|
|
45
46
|
find_ez_mismatches,
|
|
46
47
|
)
|
|
@@ -703,6 +704,7 @@ class ComputeManager:
|
|
|
703
704
|
return
|
|
704
705
|
|
|
705
706
|
mismatches = find_chirality_mismatches(data, mol)
|
|
707
|
+
mismatches += find_ambiguous_centers(data, mol)
|
|
706
708
|
ez_mismatches = find_ez_mismatches(data, mol)
|
|
707
709
|
if not mismatches and not ez_mismatches:
|
|
708
710
|
return
|
|
@@ -718,7 +720,8 @@ class ComputeManager:
|
|
|
718
720
|
count = len(mismatches) + len(ez_mismatches)
|
|
719
721
|
if report_status:
|
|
720
722
|
self.host.update_status_message(
|
|
721
|
-
f"Warning: {count} stereo element(s) differ from the 2D drawing
|
|
723
|
+
f"Warning: {count} stereo element(s) differ from the 2D drawing "
|
|
724
|
+
"or are drawn ambiguously."
|
|
722
725
|
)
|
|
723
726
|
|
|
724
727
|
def on_calculation_error(self, message: Union[str, Tuple[int, str]]) -> None:
|
|
@@ -445,9 +445,6 @@ class IOManager:
|
|
|
445
445
|
|
|
446
446
|
def load_xyz_file(self, file_path: str) -> Optional[Any]:
|
|
447
447
|
"""Load XYZ file and create RDKit Mol with charge prompt and bond determination."""
|
|
448
|
-
if not self.host.state_manager.check_unsaved_changes():
|
|
449
|
-
return None
|
|
450
|
-
|
|
451
448
|
try:
|
|
452
449
|
return self._mol_from_xyz_lines(self._read_text_lines_flexible(file_path))
|
|
453
450
|
except (RuntimeError, TypeError, ValueError, UnicodeDecodeError) as e:
|
|
@@ -1798,13 +1798,22 @@ class View3DManager:
|
|
|
1798
1798
|
|
|
1799
1799
|
def fit_to_view(self) -> None:
|
|
1800
1800
|
"""Fit all items in the scene into the view"""
|
|
1801
|
-
|
|
1801
|
+
try:
|
|
1802
|
+
old_ta = self.host.init_manager.view_2d.transformationAnchor()
|
|
1803
|
+
old_ra = self.host.init_manager.view_2d.resizeAnchor()
|
|
1804
|
+
items = self.host.init_manager.scene.items()
|
|
1805
|
+
except (AttributeError, RuntimeError, TypeError) as e:
|
|
1806
|
+
# Deferred calls (QTimer.singleShot after a load) can land after
|
|
1807
|
+
# the window is torn down; a deleted view cannot be fitted or reset.
|
|
1808
|
+
logging.debug("fit_to_view skipped, 2D view unavailable: %s", e)
|
|
1809
|
+
return
|
|
1810
|
+
if not items:
|
|
1802
1811
|
self.reset_zoom()
|
|
1803
1812
|
return
|
|
1804
1813
|
|
|
1805
1814
|
# Calculate total bounding rect of visible items
|
|
1806
1815
|
visible_items_rect = QRectF()
|
|
1807
|
-
for item in
|
|
1816
|
+
for item in items:
|
|
1808
1817
|
if item.isVisible() and not isinstance(item, TemplatePreviewItem):
|
|
1809
1818
|
if visible_items_rect.isEmpty():
|
|
1810
1819
|
visible_items_rect = item.sceneBoundingRect()
|
|
@@ -1826,12 +1835,6 @@ class View3DManager:
|
|
|
1826
1835
|
padded = QRectF(cx - w / 2.0, cy - h / 2.0, w, h)
|
|
1827
1836
|
|
|
1828
1837
|
# Temporarily set anchor to center before calling fitInView
|
|
1829
|
-
try:
|
|
1830
|
-
old_ta = self.host.init_manager.view_2d.transformationAnchor()
|
|
1831
|
-
old_ra = self.host.init_manager.view_2d.resizeAnchor()
|
|
1832
|
-
except (AttributeError, RuntimeError, TypeError):
|
|
1833
|
-
old_ta = old_ra = None
|
|
1834
|
-
|
|
1835
1838
|
try:
|
|
1836
1839
|
self.host.init_manager.view_2d.setTransformationAnchor(
|
|
1837
1840
|
QGraphicsView.ViewportAnchor.AnchorViewCenter
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/MoleditPy_linux.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/MoleditPy_linux.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/MoleditPy_linux.egg-info/top_level.txt
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
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/plugins/plugin_interface.py
RENAMED
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/plugins/plugin_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/align_plane_dialog.py
RENAMED
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/alignment_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/base_picking_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/bond_length_dialog.py
RENAMED
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/calculation_worker.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/color_settings_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/custom_interactor_style.py
RENAMED
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/custom_qt_interactor.py
RENAMED
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/dialog_3d_picking_mixin.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/edit_actions_logic.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/geometry_base_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/main_window_init.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/molecular_scene_handler.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/move_dialog_mixin.py
RENAMED
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/move_group_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/periodic_table_dialog.py
RENAMED
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/planarize_dialog.py
RENAMED
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/plugin_menu_manager.py
RENAMED
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/preview_molecule.py
RENAMED
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/sdf_record_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/settings_tabs/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/string_importers.py
RENAMED
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/template_preview_item.py
RENAMED
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/template_preview_view.py
RENAMED
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/translation_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/ui/user_template_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/utils/default_settings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.11.4 → moleditpy_linux-4.12.0}/src/moleditpy_linux/utils/sip_isdeleted_safe.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|