Source code for sknano.utils.analysis._funcs

# -*- coding: utf-8 -*-
"""
========================================================================
Structure analysis functions (:mod:`sknano.utils.analysis._funcs`)
========================================================================

.. currentmodule:: sknano.utils.analysis._funcs

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

import numpy as np

__all__ = ['find_target_atom']


[docs]def find_target_atom(atoms, target_coords=None, search_radius=1.0, nearest_target=False, max_search_radius=None): """Search for atom closest to target location. Parameters ---------- atoms : :class:`~sknano.core.atoms.Atoms` An :class:`~sknano.core.atoms.Atoms` instance. target_coords : array_like An array or list of :math:`x,y,z` coordinates search_radius : :class:`~python:float`, optional Search radius nearest_target : :class:`~python:bool`, optional max_search_radius : :class:`~python:float`, optional Returns ------- target_atom :class:`~sknano.core.atoms.Atom` An :class:`~sknano.core.atoms.Atom` instance. """ print('Starting search radius: {}'.format(search_radius)) target_atom = None if max_search_radius is None: max_search_radius = 100. * search_radius atom_tree = atoms.atom_tree while search_radius <= max_search_radius: try: target_index = None if nearest_target: target_index = \ atom_tree.query(target_coords, distance_upper_bound=search_radius)[-1] else: target_index = \ np.random.choice( atom_tree.query_ball_point(target_coords, search_radius)) target_atom = atoms[target_index] except (IndexError, ValueError): search_radius += 1 print('No target atom within search radius.\n' 'Increasing radius by 1 unit to {}'.format(search_radius)) else: print('Found target atom.') return target_atom else: print('Maximum search radius exceeded. No target atom found.') return None