Skip to content

Commit 7d729a8

Browse files
authored
Merge pull request #2960 for optimization and cython tweaks
Fix cython declarations and some optimizations in molecule.py
2 parents 3b6dd79 + 7881267 commit 7d729a8

1 file changed

Lines changed: 44 additions & 29 deletions

File tree

rmgpy/molecule/molecule.py

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,7 @@ def apply_action(self, action):
604604
required parameters. The available actions can be found
605605
:ref:`here <reaction-recipe-actions>`.
606606
"""
607+
cython.declare(act=str, i=cython.Py_ssize_t, n=cython.Py_ssize_t)
607608
# Invalidate current atom type
608609
self.atomtype = None
609610
act = action[0].upper()
@@ -612,17 +613,23 @@ def apply_action(self, action):
612613
# Nothing else to do here
613614
pass
614615
elif act == 'GAIN_RADICAL':
615-
for i in range(action[2]): self.increment_radical()
616+
n = action[2]
617+
for i in range(n): self.increment_radical()
616618
elif act == 'LOSE_RADICAL':
617-
for i in range(abs(action[2])): self.decrement_radical()
619+
n = action[2]
620+
for i in range(n): self.decrement_radical()
618621
elif act == 'GAIN_CHARGE':
619-
for i in range(action[2]): self.increment_charge()
622+
n = action[2]
623+
for i in range(n): self.increment_charge()
620624
elif act == 'LOSE_CHARGE':
621-
for i in range(abs(action[2])): self.decrement_charge()
622-
elif action[0].upper() == 'GAIN_PAIR':
623-
for i in range(action[2]): self.increment_lone_pairs()
624-
elif action[0].upper() == 'LOSE_PAIR':
625-
for i in range(abs(action[2])): self.decrement_lone_pairs()
625+
n = action[2]
626+
for i in range(n): self.decrement_charge()
627+
elif act == 'GAIN_PAIR':
628+
n = action[2]
629+
for i in range(n): self.increment_lone_pairs()
630+
elif act == 'LOSE_PAIR':
631+
n = action[2]
632+
for i in range(n): self.decrement_lone_pairs()
626633
else:
627634
raise gr.ActionError('Unable to update Atom: Invalid action {0}".'.format(action))
628635

@@ -1283,7 +1290,7 @@ def sort_atoms(self):
12831290
Placing hydrogens last during sorting ensures that functions with hydrogen
12841291
removal work properly.
12851292
"""
1286-
cython.declare(vertex=Vertex, a=Atom, index=int)
1293+
cython.declare(vertex=Vertex, index=int)
12871294
for vertex in self.vertices:
12881295
if vertex.sorting_label < 0:
12891296
self.update_connectivity_values()
@@ -1318,8 +1325,8 @@ def get_formula(self):
13181325
"""
13191326
Return the molecular formula for the molecule.
13201327
"""
1321-
cython.declare(atom=Atom, symbol=str, elements=dict, keys=list, formula=str)
1322-
cython.declare(hasCarbon=cython.bint, hasHydrogen=cython.bint)
1328+
cython.declare(atom=Atom, symbol=str, element_dict=dict, keys=list, key=str,
1329+
formula=str, count=int)
13231330

13241331
# Count the number of each element in the molecule
13251332
element_dict = {}
@@ -1391,7 +1398,7 @@ def get_num_atoms(self, element=None):
13911398
Return the number of atoms in molecule. If element is given, ie. "H" or "C",
13921399
the number of atoms of that element is returned.
13931400
"""
1394-
cython.declare(numAtoms=cython.int, atom=Atom)
1401+
cython.declare(num_atoms=cython.int, atom=Atom)
13951402
if element is None:
13961403
return len(self.vertices)
13971404
else:
@@ -1473,8 +1480,8 @@ def connect_the_dots(self, critical_distance_factor=0.45, raise_atomtype_excepti
14731480
Delete all bonds, and set them again based on the Atoms' coords.
14741481
Does not detect bond type.
14751482
"""
1476-
cython.declare(criticalDistance=float, i=int, atom1=Atom, atom2=Atom,
1477-
bond=Bond, atoms=list, zBoundary=float)
1483+
cython.declare(critical_distance=float, i=cython.Py_ssize_t, atom=Atom, atom1=Atom, atom2=Atom,
1484+
bond=Bond, atoms=list, sorted_atoms=list, z_boundary=float, distance_squared=float)
14781485
# groupBond=GroupBond,
14791486
self._fingerprint = None
14801487

@@ -1600,7 +1607,7 @@ def get_element_count(self):
16001607
"""
16011608
Returns the element count for the molecule as a dictionary.
16021609
"""
1603-
cython.declare(atom=Atom, element_count=dict, symbol=str, key=str)
1610+
cython.declare(atom=Atom, element_count=dict, symbol=str)
16041611
element_count = {}
16051612
for atom in self.vertices:
16061613
symbol = atom.element.symbol
@@ -1700,9 +1707,8 @@ def is_subgraph_isomorphic(self, other, initial_map=None, generate_initial_map=F
17001707
while the atoms of `other` are the values). The `other` parameter must
17011708
be a :class:`Group` object, or a :class:`TypeError` is raised.
17021709
"""
1703-
cython.declare(group=gr.Group, atom=Atom)
1704-
cython.declare(carbonCount=cython.short, nitrogenCount=cython.short, oxygenCount=cython.short,
1705-
sulfurCount=cython.short, radicalCount=cython.short)
1710+
cython.declare(group=gr.Group, atom=Atom, element_count=dict, element=str, count=cython.short,
1711+
result=cython.bint)
17061712
cython.declare(L=list)
17071713
# It only makes sense to compare a Molecule to a Group for subgraph
17081714
# isomorphism, so raise an exception if this is not what was requested
@@ -1776,9 +1782,7 @@ def find_subgraph_isomorphisms(self, other, initial_map=None, save_order=False):
17761782
The `other` parameter must be a :class:`Group` object, or a
17771783
:class:`TypeError` is raised.
17781784
"""
1779-
cython.declare(group=gr.Group, atom=Atom)
1780-
cython.declare(carbonCount=cython.short, nitrogenCount=cython.short, oxygenCount=cython.short,
1781-
sulfurCount=cython.short, radicalCount=cython.short)
1785+
cython.declare(group=gr.Group, element_count=dict, element=str, count=cython.short, result=list)
17821786

17831787
# It only makes sense to compare a Molecule to a Group for subgraph
17841788
# isomorphism, so raise an exception if this is not what was requested
@@ -1940,7 +1944,7 @@ def to_single_bonds(self, raise_atomtype_exception=True):
19401944
This is useful for isomorphism comparison against something that was made
19411945
via from_xyz, which does not attempt to perceive bond orders
19421946
"""
1943-
cython.declare(atom1=Atom, atom2=Atom, bond=Bond, newMol=Molecule, atoms=list, mapping=dict)
1947+
cython.declare(atom1=Atom, atom2=Atom, bond=Bond, new_mol=Molecule, atoms=list, mapping=dict)
19441948

19451949
new_mol = Molecule()
19461950
atoms = self.vertices
@@ -2208,7 +2212,7 @@ def is_aromatic(self):
22082212
there will be at least one 6 membered aromatic ring so this algorithm
22092213
will not fail for fused aromatic rings.
22102214
"""
2211-
cython.declare(rc=list, cycle=list, atom=Atom)
2215+
cython.declare(rings=list, cycle=list, atom=Atom)
22122216
rings = self.get_smallest_set_of_smallest_rings()
22132217
if rings:
22142218
for cycle in rings:
@@ -2402,7 +2406,7 @@ def update_lone_pairs(self):
24022406
Iterate through the atoms in the structure and calculate the
24032407
number of lone electron pairs, assuming a neutral molecule.
24042408
"""
2405-
cython.declare(atom1=Atom, atom2=Atom, bond12=Bond, order=cython.double)
2409+
cython.declare(atom1=Atom, order=cython.double)
24062410
for atom1 in self.vertices:
24072411
if atom1.is_hydrogen() or atom1.is_surface_site() or atom1.is_electron() or atom1.is_lithium():
24082412
atom1.lone_pairs = 0
@@ -2419,8 +2423,19 @@ def get_net_charge(self):
24192423
Iterate through the atoms in the structure and calculate the net charge
24202424
on the overall molecule.
24212425
"""
2422-
cython.declare(atom=Atom)
2423-
return sum([atom.charge for atom in self.vertices])
2426+
# return sum(atom.charge for atom in self.vertices)
2427+
cython.declare(
2428+
i=cython.Py_ssize_t,
2429+
n=cython.Py_ssize_t,
2430+
total=cython.int,
2431+
atom=Atom,
2432+
)
2433+
total = 0
2434+
n = len(self.vertices)
2435+
for i in range(n):
2436+
atom = self.vertices[i]
2437+
total += atom.charge
2438+
return total
24242439

24252440
def get_charge_span(self):
24262441
"""
@@ -2575,7 +2590,7 @@ def get_aromatic_rings(self, rings=None, save_order=False):
25752590
return [], []
25762591

25772592
cython.declare(rd_atom_indices=dict, ob_atom_ids=dict, aromatic_rings=list, aromatic_bonds=list)
2578-
cython.declare(ring0=list, i=cython.int, atom1=Atom, atom2=Atom)
2593+
cython.declare(ring0=list, i=cython.Py_ssize_t, atom1=Atom, atom2=Atom)
25792594

25802595
from rdkit.Chem.rdchem import BondType
25812596
AROMATIC = BondType.AROMATIC
@@ -2584,7 +2599,7 @@ def get_aromatic_rings(self, rings=None, save_order=False):
25842599
rings = self.get_smallest_set_of_smallest_rings()
25852600

25862601
# Remove rings that share more than 3 atoms, since they cannot be planar
2587-
cython.declare(toRemove=set, j=cython.int, toRemoveSorted=list)
2602+
cython.declare(to_remove=set, j=cython.Py_ssize_t, to_remove_sorted=list)
25882603
if len(rings) < 2:
25892604
pass
25902605
else:
@@ -3157,7 +3172,7 @@ def get_ring_count_in_largest_fused_ring_system(self) -> int:
31573172
Returns 0 if the molecule has no fused rings (only monocycles or no rings).
31583173
"""
31593174
cython.declare(polycycles=list, sssr=list, sssr_sets=list, ring_counts=list)
3160-
cython.declare(polycycle=list, ring=list)
3175+
cython.declare(polycycle=list, poly_set=set, ring_set=set, ring_count=cython.int)
31613176

31623177
polycycles = self.get_polycycles()
31633178
if not polycycles:

0 commit comments

Comments
 (0)