Skip to content

Commit

Permalink
morgan algorithm fixed.
Browse files Browse the repository at this point in the history
  • Loading branch information
stsouko committed Mar 11, 2021
1 parent dda0457 commit 2a00dfd
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 11 deletions.
5 changes: 3 additions & 2 deletions CGRtools/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright 2014-2020 Ramil Nugmanov <nougmanoff@protonmail.com>
# Copyright 2014-2021 Ramil Nugmanov <nougmanoff@protonmail.com>
# Copyright 2014-2019 Timur Madzhidov tmadzhidov@gmail.com features and API discussion
# Copyright 2014-2019 Alexandre Varnek <varnek@unistra.fr> base idea of CGR approach
# This file is part of CGRtools.
#
Expand All @@ -24,7 +25,7 @@
from .utils import *


smiles = SMILESRead.create_parser(ignore=True)
smiles = SMILESRead.create_parser(ignore=True, remap=False)
xyz = XYZRead.create_parser()


Expand Down
61 changes: 60 additions & 1 deletion CGRtools/algorithms/components/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,16 @@
#
from CachedMethods import cached_property, FrozenDict
from collections import defaultdict, deque
from importlib.util import find_spec
from typing import List, Tuple, Dict, Set, Any, Union


if find_spec('numpy') and find_spec('numba'): # try to load numba jit
from numpy import uint64, zeros
else:
zeros = None


class GraphComponents:
__slots__ = ()

Expand Down Expand Up @@ -109,12 +116,64 @@ def connected_rings(self) -> Tuple[Tuple[int, ...], ...]:
out.append(tuple(r))
return tuple(out)

def adjacency_matrix(self, set_bonds=False):
"""
Adjacency matrix of Graph.
:param set_bonds: if True set bond orders instead of 1.
"""
if zeros is None:
raise ImportError('numpy required')

adj = zeros((len(self), len(self)), dtype=uint64)
mapping = {n: x for x, n in enumerate(self._atoms)}
if set_bonds:
for n, ms in self._bonds.items():
n = mapping[n]
for m, b in ms.items():
adj[n, mapping[m]] = int(b)
else:
for n, ms in self._bonds.items():
n = mapping[n]
for m, b in ms.items():
adj[n, mapping[m]] = 1
return adj

@cached_property
def ring_atoms(self):
"""
Atoms in rings
"""
return {x for x in self.sssr for x in x}
bonds = self._skin_graph(self._bonds)
if not bonds:
return frozenset()

in_rings = set()
atoms = set(bonds)
while atoms:
stack = deque([(atoms.pop(), 0, 0)])
path = []
seen = set()
while stack:
c, p, d = stack.pop()
if len(path) > d:
path = path[:d]
if c in in_rings:
continue
path.append(c)
seen.add(c)

d += 1
for n in bonds[c]:
if n == p:
continue
elif n in seen:
in_rings.update(path[path.index(n):])
else:
stack.append((n, c, d))

atoms.difference_update(seen)
return in_rings

@cached_property
def rings_count(self):
Expand Down
11 changes: 4 additions & 7 deletions CGRtools/algorithms/morgan.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright 2017-2020 Ramil Nugmanov <nougmanoff@protonmail.com>
# Copyright 2017-2021 Ramil Nugmanov <nougmanoff@protonmail.com>
# This file is part of CGRtools.
#
# CGRtools is free software; you can redistribute it and/or modify
Expand All @@ -17,7 +17,6 @@
# along with this program; if not, see <https://www.gnu.org/licenses/>.
#
from CachedMethods import cached_property
from collections import Counter
from itertools import groupby
from logging import warning
from operator import itemgetter
Expand All @@ -40,7 +39,8 @@ def atoms_order(self) -> Dict[int, int]:
return {}
elif len(atoms) == 1: # optimize single atom containers
return dict.fromkeys(atoms, 1)
return self._morgan({n: hash(a) for n, a in atoms.items()})
ring = self.ring_atoms
return self._morgan({n: tuple_hash((hash(a), n in ring)) for n, a in atoms.items()})

def _morgan(self, weights: Dict[int, int]) -> Dict[int, int]:
atoms = self._atoms
Expand All @@ -58,10 +58,7 @@ def _morgan(self, weights: Dict[int, int]) -> Dict[int, int]:
if numb == len(atoms): # each atom now unique
break
elif numb == old_numb: # not changed. molecules like benzene
if min(Counter(weights.values()).items(), key=itemgetter(1))[1] > 1:
if stab == 3:
break
elif stab >= 2:
if stab == 3:
break
stab += 1
elif stab: # changed unique atoms number. reset stability check.
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def finalize_options(self):

setup(
name='CGRtools',
version='4.1.15',
version='4.1.16',
packages=['CGRtools', 'CGRtools.algorithms', 'CGRtools.algorithms.components', 'CGRtools.containers',
'CGRtools.files', 'CGRtools.files._mdl', 'CGRtools.periodictable', 'CGRtools.periodictable.element',
'CGRtools.utils', 'CGRtools.attributes'],
Expand Down

0 comments on commit 2a00dfd

Please sign in to comment.