Skip to content

Commit

Permalink
grid depict functions added.
Browse files Browse the repository at this point in the history
  • Loading branch information
stsouko committed Mar 21, 2021
1 parent ec181a9 commit 3837340
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 33 deletions.
42 changes: 12 additions & 30 deletions CGRtools/algorithms/depict.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,22 @@ def depict(self, *, embedding=False):

svg = [f'<svg width="{width:.2f}cm" height="{height:.2f}cm" '
f'viewBox="{viewbox_x:.2f} {viewbox_y:.2f} {width:.2f} '
f'{height:.2f}" xmlns="http://www.w3.org/2000/svg" version="1.1">\n <g>']
f'{height:.2f}" xmlns="http://www.w3.org/2000/svg" version="1.1">']
svg.extend(self._graph_svg(atoms, bonds, masks, viewbox_x, viewbox_y, width, height))
svg.append('</svg>')
return '\n'.join(svg)

@classmethod
def _graph_svg(cls, atoms, bonds, masks, viewbox_x, viewbox_y, width, height):
config = cls._render_config
svg = [' <g>']
if bonds:
if masks:
uid = str(uuid4())
svg.append(f' <defs>\n <mask id="mask-{uid}">\n'
f' <rect x="{viewbox_x:.2f}" y="{viewbox_y:.2f}" '
f'width="{width:.2f}" height="{height:.2f}" fill="white"/>')
svg.extend(self._masks_svg(masks))
svg.extend(cls._masks_svg(masks))
svg.append(' </mask>\n </defs>\n'
f' <g fill="none" stroke="{config["bond_color"]}" '
f'stroke-width="{config["bond_width"]:.2f}" mask="url(#mask-{uid})">')
Expand All @@ -109,9 +116,8 @@ def depict(self, *, embedding=False):
svg.append(' <g font-family="monospace">')
svg.extend(atoms)
svg.append(' </g>')

svg.append(' </g>\n</svg>')
return '\n'.join(svg)
svg.append(' </g>')
return svg

@classmethod
def _masks_svg(cls, masks):
Expand Down Expand Up @@ -504,31 +510,7 @@ def depict(self):
svg.append(' </g>')

for atoms, bonds, masks in zip(r_atoms, r_bonds, r_masks):
svg.append(' <g>')
if bonds:
if masks:
uid = str(uuid4())
svg.append(f' <defs>\n <mask id="mask-{uid}">\n'
f' <rect x="{viewbox_x:.2f}" y="{viewbox_y:.2f}" '
f'width="{width:.2f}" height="{height:.2f}" fill="white"/>')
svg.extend(Depict._masks_svg(masks))
svg.append(' </mask>\n </defs>\n'
f' <g fill="none" stroke="{config["bond_color"]}" '
f'stroke-width="{config["bond_width"]:.2f}" mask="url(#mask-{uid})">')
if len(bonds) == 1: # SVG BUG adhoc
svg.append(f' <line x1="{viewbox_x:.2f}" y1="{viewbox_y:.2f}" '
f'x2="{viewbox_x + width:.2f}" y2="{viewbox_y:.2f}" stroke="none"/>')
else:
svg.append(f' <g fill="none" stroke="{config["bond_color"]}" '
f'stroke-width="{config["bond_width"]:.2f}">')
svg.extend(bonds)
svg.append(' </g>')

if atoms:
svg.append(' <g font-family="monospace">')
svg.extend(atoms)
svg.append(' </g>')
svg.append(' </g>')
svg.extend(Depict._graph_svg(atoms, bonds, masks, viewbox_x, viewbox_y, width, height))
svg.append('</svg>')
return '\n'.join(svg)

Expand Down
5 changes: 3 additions & 2 deletions CGRtools/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright 2019, 2020 Ramil Nugmanov <nougmanoff@protonmail.com>
# Copyright 2019-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 @@ -18,9 +18,10 @@
#
from importlib.util import find_spec
from .functional_groups import functional_groups
from .grid import grid_depict


__all__ = ['functional_groups']
__all__ = ['functional_groups', 'grid_depict']


if find_spec('rdkit'):
Expand Down
1 change: 1 addition & 0 deletions CGRtools/utils/functional_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, see <https://www.gnu.org/licenses/>.
#


def functional_groups(molecule, limit):
Expand Down
78 changes: 78 additions & 0 deletions CGRtools/utils/grid.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-
#
# Copyright 2021 Ramil Nugmanov <nougmanoff@protonmail.com>
# This file is part of CGRtools.
#
# CGRtools is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, see <https://www.gnu.org/licenses/>.
#
from itertools import zip_longest
from typing import List, Tuple, Union
from ..containers import MoleculeContainer, QueryContainer, CGRContainer, QueryCGRContainer

graphs = Union[MoleculeContainer, QueryContainer, CGRContainer, QueryCGRContainer]


def grid_depict(molecules: Union[List[graphs], Tuple[graphs, ...]], cols: int = 3):
"""
Depict molecules grid.
:param cols: number of molecules per row.
"""
config = MoleculeContainer._render_config
font_size = config['font_size']
font125 = 1.25 * font_size

planes = []
render = []
shift_y = shift_x = 0.
for ms in zip_longest(*[iter(molecules)] * cols):
height = 0.
for m in ms:
if m is None:
break
min_y = min(y for x, y in m._plane.values())
max_y = max(y for x, y in m._plane.values())
h = max_y - min_y
if height < h: # get height of row
height = h
planes.append(m._plane.copy())

# now align mols by height
shift_y -= height / 2. + 2.
max_x = 0.
for m in ms:
if m is None:
break
max_x = m._fix_plane_mean(max_x, shift_y) + 2.
render.append(m.depict(embedding=True)[:3])
if max_x > shift_x: # get total width
shift_x = max_x
shift_y -= height / 2.

# restore planes
for p, m in zip(planes, molecules):
m._plane = p

width = shift_x + 3.0 * font_size
height = -shift_y + 2.5 * font_size
svg = [f'<svg width="{width:.2f}cm" height="{height:.2f}cm" '
f'viewBox="{-font125:.2f} {-font125:.2f} {width:.2f} '
f'{height:.2f}" xmlns="http://www.w3.org/2000/svg" version="1.1">']
for atoms, bonds, masks in render:
svg.extend(MoleculeContainer._graph_svg(atoms, bonds, masks, -font125, -font125, width, height))
svg.append('</svg>')
return '\n'.join(svg)


__all__ = ['grid_depict']
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.16',
version='4.1.17',
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 3837340

Please sign in to comment.