Source code for skchem.forcefields.base

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

"""
## skchem.forcefields.base

Module specifying base class for forcefields.
"""
import warnings
from abc import ABCMeta, abstractmethod

import pandas as pd
from rdkit.Chem.rdDistGeom import EmbedMolecule

from ..utils import Suppressor
from ..base import Transformer
from ..filters.base import TransformFilter


[docs]class ForceField(Transformer, TransformFilter): # TODO: Multiple conformer generation handling. """ Base forcefield class. Filter drops those that fail to be optimized. """ __metaclass__ = ABCMeta def __init__(self, preembed=True, warn_on_fail=True, error_on_fail=False, add_hs=True, n_jobs=1, verbose=True): self.add_hs = add_hs self.warn_on_fail = warn_on_fail self.error_on_fail = error_on_fail self.preembed = preembed super(ForceField, self).__init__(verbose=verbose, n_jobs=n_jobs) @property def columns(self): return pd.Index(['structure'])
[docs] def embed(self, mol): success = EmbedMolecule(mol) if success == -1: msg = 'Failed to Embed Molecule {}'.format(mol.name) if self.error_on_fail: raise RuntimeError(msg) elif self.warn_on_fail: warnings.warn(msg) return None if self.add_hs: return mol.add_hs(add_coords=True) else: return mol
def _transform_mol(self, mol): mol = mol.copy() with Suppressor(): if self.preembed: mol = self.embed(mol) if mol is None: # embedding failed return None res = self._optimize(mol) if res == -1: msg = 'Failed to optimize molecule \'{}\' using {}'.format( mol.name, self.__class__) if self.error_on_fail: raise RuntimeError(msg) elif self.warn_on_fail: warnings.warn(msg) return None return mol @abstractmethod def _optimize(self, mol): pass
[docs]class RoughEmbedding(ForceField): def _optimize(self, mol): return mol