Source code for sknano.core.atoms.vdW_atoms

# -*- coding: utf-8 -*-
"""
===============================================================================
Atom classes with van der Waals radius (:mod:`sknano.core.atoms.vdW_atoms`)
===============================================================================

.. currentmodule:: sknano.core.atoms.vdW_atoms

"""
from __future__ import absolute_import, division, print_function
from __future__ import unicode_literals

__docformat__ = 'restructuredtext en'

from operator import attrgetter
import numbers
import numpy as np

from sknano.core.refdata import element_data
from .atoms import Atom, Atoms

__all__ = ['VanDerWaalsAtom', 'VanDerWaalsAtoms', 'vdw_radius_from_basis']


[docs]class VanDerWaalsAtom(Atom): """An `Atom` class with a van der Waals radius attribute. Parameters ---------- element : {str, int}, optional A string representation of the element symbol or an integer specifying an element atomic number. r_vdw : float, optional """ def __init__(self, *args, r_vdw=0., **kwargs): super().__init__(*args, **kwargs) self.r_vdw = r_vdw self.fmtstr = super().fmtstr + ", r_vdw={r_vdw!r}" # def __eq__(self, other): # return np.allclose(self.r_vdw, other.r_vdw) and super().__eq__(other) # def __lt__(self, other): # return (self.r_vdw < other.r_vdw and super().__le__(other)) or \ # (self.r_vdw <= other.r_vdw and super().__lt__(other)) def __eq__(self, other): if not self._is_valid_operand(other): return NotImplemented return np.allclose(self.r_vdw, other.r_vdw) and super().__eq__(other) def __le__(self, other): if not self._is_valid_operand(other): return NotImplemented if self.r_vdw > other.r_vdw or not super().__le__(other): return False return True def __lt__(self, other): if not self._is_valid_operand(other): return NotImplemented if self.r_vdw >= other.r_vdw or not super().__lt__(other): return False return True def __ge__(self, other): if not self._is_valid_operand(other): return NotImplemented if self.r_vdw < other.r_vdw or not super().__ge__(other): return False return True def __gt__(self, other): if not self._is_valid_operand(other): return NotImplemented if self.r_vdw <= other.r_vdw or not super().__gt__(other): return False return True def __dir__(self): attrs = super().__dir__() attrs.append('r_vdw') return attrs @property def r_vdw(self): """van der Waals radius :math:`r_{\\mathrm{vdW}}` in units of \ :math:`\\AA`. """ return self._r_vdw @r_vdw.setter def r_vdw(self, value): """Set `VanDerWaalsAtom` radius :math:`r_{\\mathrm{vdw}}`. Parameters ---------- value : float van der Waals radius in units of :math:`\\AA`. """ if not isinstance(value, numbers.Number): raise TypeError('Expected a number') self._r_vdw = float(value)
[docs] def todict(self): super_dict = super().todict() super_dict.update(dict(r_vdw=self.r_vdw)) return super_dict
[docs]class VanDerWaalsAtoms(Atoms): """An `Atoms` sub-class for `VanDerWaalsAtom`\ s. A container class for `VanDerWaalsAtom` objects. Parameters ---------- atoms : {None, sequence, `VanDerWaalsAtoms`}, optional if not `None`, then a list of `VanDerWaalsAtom` instance objects or an existing `VanDerWaalsAtoms` instance object. """ @property def __atom_class__(self): return VanDerWaalsAtom def sort(self, key=attrgetter('r_vdw'), reverse=False): super().sort(key=key, reverse=reverse) @property def r_vdw(self): """Return array of `VanDerWaalsAtom` van der Waals radii.""" return np.asarray([atom.r_vdw for atom in self])
[docs]def vdw_radius_from_basis(*args): """Helper function to return the maximum van der Waals radius from a \ tuple of atoms.""" r_vdw = 0 for atom in args: try: element = atom.element except AttributeError: element = atom try: r_vdw = max(r_vdw, element_data[element]['VanDerWaalsRadius']) except TypeError: try: r_vdw = max(r_vdw, element_data[element]['AtomicRadius']) except TypeError: pass return r_vdw