Source code for skchem.core.bond

#! /usr/bin/env python
#
# Copyright (C) 2015-2016 Rich Lewis <rl403@cam.ac.uk>
# License: 3-clause BSD

"""
## skchem.core.bond

Defining chemical bonds in scikit-chem.
"""

from itertools import chain, combinations

import pandas as pd
import rdkit.Chem
import numpy as np

from .atom import Atom
from .base import ChemicalObject, PropertyView, ChemicalObjectView


[docs]class Bond(rdkit.Chem.rdchem.Bond, ChemicalObject): """ Class representing a chemical bond in scikit-chem. """ @property def index(self): """ int: the index of the bond in the atom. """ return self.GetIdx() @property def atoms(self): """ tuple[Atom]: list of atoms involved in the bond. """ return (Atom.from_super(self.GetBeginAtom()), Atom.from_super(self.GetEndAtom())) @property def atom_idxs(self): """ tuple[int]: list of atom indexes involved in the bond. """ return (self.GetBeginAtomIdx(), self.GetEndAtomIdx()) @property def props(self): """ PropertyView: rdkit properties of the atom. """ if not hasattr(self, '_props'): self._props = PropertyView(self) return PropertyView(self) @property def order(self): """ int: the order of the bond. """ return self.GetBondTypeAsDouble() @property def is_aromatic(self): """ bool: whether the bond is aromatic. """ return self.GetIsAromatic() @property def is_conjugated(self): """ bool: whether the bond is conjugated. """ return self.GetIsConjugated() @property def owner(self): """ skchem.Mol: the molecule this bond is a part of. """ from .mol import Mol return Mol.from_super(self.GetOwningMol()) @property def stereo_symbol(self): """ str: the stereo label of the bond ('Z', 'E', 'ANY', 'NONE') """ return self.GetStereo().name.lstrip('STEREO') @property def is_in_ring(self): """ bool: whether the bond is in a ring. """ return self.IsInRing()
[docs] def draw(self): """ str: Draw the bond in ascii. """ return '{}{}{}'.format(self.atoms[0].symbol, '-' if self.order == 1 else self.GetSmarts(), self.atoms[1].symbol)
[docs] def to_dict(self): """ dict: Convert to a dictionary representation. """ return {"b": self.GetBeginAtomIdx(), "e": self.GetEndAtomIdx(), "o": self.order}
def __repr__(self): return '<{klass} type="{bond}" at {address}>'.format( klass=self.__class__.__name__, bond=self.draw(), address=hex(id(self))) def __str__(self): return self.draw()
class BondView(ChemicalObjectView): """ Bond interface wrapper """ def __getitem__(self, index): res = super(BondView, self).__getitem__(index) if res is None: if abs(index) >= len(self): raise IndexError('Index {} out of range for molecule with ' '{} bonds.'.format(index, len(self))) # index is negative, so adding gives desired indexing from back if index < 0: index += len(self) return Bond.from_super(self.owner.GetBondWithIdx(index)) else: return res def __len__(self): return self.owner.GetNumBonds() @property def atom_idxs(self): """ The atom indices for the bonds in the view. """ return np.array([atom.atom_idxs for atom in self]) @property def order(self): """ np.array<int> the bond orders of the bonds in the view. """ return np.array([bond.order for bond in self]) @property def is_aromatic(self): """ np.array<bool> whether each of the bonds in the view are aromatic. """ return np.array([bond.is_aromatic for bond in self]) @property def is_conjugated(self): """ np.array<bool> whether each of the bonds in the view are c onjugated. """ return np.array([bond.is_conjugated for bond in self]) @property def is_in_ring(self): """ np.array<bool> whether each of the bonds in the view are in a ring. """ return np.array([bond.is_in_ring for bond in self]) @property def stereo_symbol(self): """ np.array<str> the stereo symbol of the bonds in the view. """ return np.array([bond.stereo_symbol for bond in self]) @property def index(self): """ pd.Index: an index of the bonds in the `BondView`. """ return pd.RangeIndex(len(self), name='bond_idx') def adjacency_matrix(self): """ np.array[int]: the bond adjacency matrix. """ res = np.zeros((len(self), len(self))) ixs = zip(*chain(*(combinations((bond.index for bond in atom.bonds), 2) for atom in self.owner.atoms))) res[tuple(ixs)] = 1 res += res.T return res.astype(int) __all__ = ['Atom', 'AtomView']