Source code for sknano.core.atoms._neighbor_atoms
# -*- coding: utf-8 -*-
"""
===============================================================================
Mixin Atom classes for NN analysis (:mod:`sknano.core.atoms._neighbor_atoms`)
===============================================================================
.. currentmodule:: sknano.core.atoms._neighbor_atoms
"""
from __future__ import absolute_import, division, print_function
from __future__ import unicode_literals
__docformat__ = 'restructuredtext en'
from sknano.core import ordinal_form
__all__ = ['NeighborAtomMixin', 'NeighborAtomsMixin']
[docs]class NeighborAtomMixin:
"""Mixin class for neighbor analysis."""
@property
def first_neighbors(self):
return self._first_neighbors
@first_neighbors.setter
def first_neighbors(self, value):
self._first_neighbors = value
@property
def second_neighbors(self):
return self._second_neighbors
@second_neighbors.setter
def second_neighbors(self, value):
self._second_neighbors = value
@property
def third_neighbors(self):
return self._third_neighbors
@third_neighbors.setter
def third_neighbors(self, value):
self._third_neighbors = value
[docs] def get_neighbors(self, n):
if n == 1:
return self.first_neighbors
elif n == 2:
return self.second_neighbors
elif n == 3:
return self.third_neighbors
else:
return getattr(self, '_{}_neighbors'.format(ordinal_form(n)))
[docs] def set_neighbors(self, n, neighbors):
if n == 1:
self._first_neighbors = neighbors
elif n == 2:
try:
for neighbor in self.first_neighbors:
if neighbor in neighbors:
neighbors.remove(neighbor)
except TypeError:
pass
self._second_neighbors = neighbors
elif n == 3:
try:
for neighbor in self.first_neighbors:
if neighbor in neighbors:
neighbors.remove(neighbor)
for neighbor in self.second_neighbors:
if neighbor in neighbors:
neighbors.remove(neighbor)
except TypeError:
pass
self._third_neighbors = neighbors
else:
try:
for neighbor in self.first_neighbors:
if neighbor in neighbors:
neighbors.remove(neighbor)
for neighbor in self.second_neighbors:
if neighbor in neighbors:
neighbors.remove(neighbor)
for neighbor in self.third_neighbors:
if neighbor in neighbors:
neighbors.remove(neighbor)
except TypeError:
pass
for i in range(4, n):
for neighbor in self.get_neighbors(i):
if neighbor in neighbors:
neighbors.remove(neighbor)
setattr(self, '_{}_neighbors'.format(ordinal_form(n)), neighbors)
[docs]class NeighborAtomsMixin:
"""Mixin :class:`~sknano.core.atoms.Atoms` class for NN analysis."""
[docs] def update_neighbors(self, cutoffs=None):
super().update_attrs()
if cutoffs is not None:
for n, cutoff in enumerate(cutoffs, start=1):
try:
NNd, NNi = self.query_atom_tree(k=self.kNN, rc=cutoff)
for j, atom in enumerate(self):
neighbors = self.__class__(
[self[NNi[j][k]] for k, d in
enumerate(NNd[j]) if d <= cutoff],
casttype=False, **self.kwargs)
neighbors.distances = \
[NNd[j][k] for k, d in enumerate(NNd[j])
if d <= cutoff]
atom.set_neighbors(n, neighbors)
except ValueError:
pass
@property
def first_neighbors(self):
return [atom.first_neighbors for atom in self]
@property
def second_neighbors(self):
return [atom.second_neighbors for atom in self]
@property
def third_neighbors(self):
return [atom.third_neighbors for atom in self]
[docs] def get_neighbors(self, n):
return [getattr(atom, '_{}_neighbors'.format(ordinal_form(n)))
for atom in self]