From c4125b1447123d554d85d2fa26c0c0f414d846ab Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Wed, 28 Aug 2024 19:28:21 -0700 Subject: [PATCH 1/8] feat: add PBC handler decorator --- src/py/mat3ra/made/tools/analyze.py | 2 + src/py/mat3ra/made/tools/utils/__init__.py | 52 ++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/src/py/mat3ra/made/tools/analyze.py b/src/py/mat3ra/made/tools/analyze.py index 889b6a88..7b5ec8a4 100644 --- a/src/py/mat3ra/made/tools/analyze.py +++ b/src/py/mat3ra/made/tools/analyze.py @@ -1,6 +1,7 @@ from typing import Callable, List, Literal, Optional import numpy as np +from .utils import decorator_handle_periodic_boundary_conditions from scipy.spatial import cKDTree from ..material import Material @@ -415,6 +416,7 @@ def get_coordination_numbers( return coordination_numbers +@decorator_handle_periodic_boundary_conditions(cutoff=3.0) def get_undercoordinated_atom_indices( material: Material, indices: List[int], diff --git a/src/py/mat3ra/made/tools/utils/__init__.py b/src/py/mat3ra/made/tools/utils/__init__.py index 95c961eb..ece960b1 100644 --- a/src/py/mat3ra/made/tools/utils/__init__.py +++ b/src/py/mat3ra/made/tools/utils/__init__.py @@ -106,3 +106,55 @@ def transform_coordinate_to_supercell( if reverse: converted_array = (np_coordinate - np_translation_vector) * np_scaling_factor return converted_array.tolist() + + +def decorator_handle_periodic_boundary_conditions(cutoff): + def decorator(func): + @wraps(func) + def wrapper(material, *args, **kwargs): + # Augment material with periodic images + augmented_material, original_count = augment_material_with_periodic_images(material, cutoff) + + # Call the original function with augmented material + result = func(augmented_material, *args, **kwargs) + + # Filter results to include only original atoms + if isinstance(result, list): # Assuming result is a list of indices + result = [idx for idx in result if idx < original_count] + return result + + return wrapper + + return decorator + + +def augment_material_with_periodic_images(material, cutoff): + """Augment the material's dataset by adding atoms from periodic images near boundaries.""" + from ..build.utils import merge_materials + from ..modify import filter_by_box, translate_by_vector + + material = material.clone() + original_count = len(material.basis.coordinates.values) + material_slice_x1 = filter_by_box(material, [0, 0, 0], [cutoff, 1, 1]) + material_slice_x2 = filter_by_box(material, [1 - cutoff, 0, 0], [1, 1, 1]) + translated_material_slice_x1 = translate_by_vector(material_slice_x1, [1, 0, 0]) + translated_material_slice_x2 = translate_by_vector(material_slice_x2, [-1, 0, 0]) + augmented_material_x = merge_materials([material, translated_material_slice_x1, translated_material_slice_x2]) + + material_slice_y1 = filter_by_box(augmented_material_x, [-cutoff, 0, 0], [1 + cutoff, cutoff, 1]) + material_slice_y2 = filter_by_box(augmented_material_x, [-cutoff, 1 - cutoff, 0], [1 + cutoff, 1, 1]) + translated_material_slice_y1 = translate_by_vector(material_slice_y1, [0, 1, 0]) + translated_material_slice_y2 = translate_by_vector(material_slice_y2, [0, -1, 0]) + augmented_material_y = merge_materials( + [augmented_material_x, translated_material_slice_y1, translated_material_slice_y2] + ) + + material_slice_z1 = filter_by_box(augmented_material_y, [-cutoff, -cutoff, 0], [1 + cutoff, 1 + cutoff, cutoff]) + material_slice_z2 = filter_by_box(augmented_material_y, [-cutoff, -cutoff, 1 - cutoff], [1 + cutoff, 1 + cutoff, 1]) + translated_material_slice_z1 = translate_by_vector(material_slice_z1, [0, 0, 1]) + translated_material_slice_z2 = translate_by_vector(material_slice_z2, [0, 0, -1]) + augmented_material = merge_materials( + [augmented_material_y, translated_material_slice_z1, translated_material_slice_z2] + ) + + return augmented_material, original_count From 8e1e69263e1823583c95b1187618f706323b814b Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Wed, 28 Aug 2024 19:56:23 -0700 Subject: [PATCH 2/8] udpate: optimize performance and deps --- src/py/mat3ra/made/tools/analyze.py | 3 +- src/py/mat3ra/made/tools/utils/__init__.py | 83 ++++++++++++++-------- 2 files changed, 57 insertions(+), 29 deletions(-) diff --git a/src/py/mat3ra/made/tools/analyze.py b/src/py/mat3ra/made/tools/analyze.py index 7b5ec8a4..d3ae305f 100644 --- a/src/py/mat3ra/made/tools/analyze.py +++ b/src/py/mat3ra/made/tools/analyze.py @@ -350,6 +350,7 @@ def shadowing_check(z: float, neighbors_indices: List[int], surface: SurfaceType ) +@decorator_handle_periodic_boundary_conditions(cutoff=3.0) def get_surface_atom_indices( material: Material, surface: SurfaceTypes = SurfaceTypes.TOP, shadowing_radius: float = 2.5, depth: float = 5 ) -> List[int]: @@ -416,7 +417,7 @@ def get_coordination_numbers( return coordination_numbers -@decorator_handle_periodic_boundary_conditions(cutoff=3.0) +@decorator_handle_periodic_boundary_conditions(cutoff=0.1) def get_undercoordinated_atom_indices( material: Material, indices: List[int], diff --git a/src/py/mat3ra/made/tools/utils/__init__.py b/src/py/mat3ra/made/tools/utils/__init__.py index ece960b1..c3fd325d 100644 --- a/src/py/mat3ra/made/tools/utils/__init__.py +++ b/src/py/mat3ra/made/tools/utils/__init__.py @@ -2,6 +2,7 @@ from typing import Callable, List, Optional import numpy as np +from mat3ra.made.material import Material from mat3ra.utils.matrix import convert_2x2_to_3x3 from ..third_party import PymatgenStructure @@ -119,7 +120,7 @@ def wrapper(material, *args, **kwargs): result = func(augmented_material, *args, **kwargs) # Filter results to include only original atoms - if isinstance(result, list): # Assuming result is a list of indices + if isinstance(result, list): result = [idx for idx in result if idx < original_count] return result @@ -128,33 +129,59 @@ def wrapper(material, *args, **kwargs): return decorator -def augment_material_with_periodic_images(material, cutoff): - """Augment the material's dataset by adding atoms from periodic images near boundaries.""" - from ..build.utils import merge_materials - from ..modify import filter_by_box, translate_by_vector +def filter_and_translate(coordinates: np.ndarray, elements: np.ndarray, axis: int, cutoff: float, direction: int): + """ + Filter and translate atom coordinates based on the axis and direction. + + Args: + coordinates (np.ndarray): The coordinates of the atoms. + elements (np.ndarray): The elements of the atoms. + axis (int): The axis to filter and translate. + cutoff (float): The cutoff value for filtering. + direction (int): The direction to translate. + + Returns: + Tuple[np.ndarray, np.ndarray]: The filtered and translated coordinates and elements. + """ + mask = (coordinates[:, axis] < cutoff) if direction == 1 else (coordinates[:, axis] > (1 - cutoff)) + filtered_coordinates = coordinates[mask] + filtered_elements = elements[mask] + translation_vector = np.zeros(3) + translation_vector[axis] = direction + translated_coordinates = filtered_coordinates + translation_vector + return translated_coordinates, filtered_elements - material = material.clone() - original_count = len(material.basis.coordinates.values) - material_slice_x1 = filter_by_box(material, [0, 0, 0], [cutoff, 1, 1]) - material_slice_x2 = filter_by_box(material, [1 - cutoff, 0, 0], [1, 1, 1]) - translated_material_slice_x1 = translate_by_vector(material_slice_x1, [1, 0, 0]) - translated_material_slice_x2 = translate_by_vector(material_slice_x2, [-1, 0, 0]) - augmented_material_x = merge_materials([material, translated_material_slice_x1, translated_material_slice_x2]) - - material_slice_y1 = filter_by_box(augmented_material_x, [-cutoff, 0, 0], [1 + cutoff, cutoff, 1]) - material_slice_y2 = filter_by_box(augmented_material_x, [-cutoff, 1 - cutoff, 0], [1 + cutoff, 1, 1]) - translated_material_slice_y1 = translate_by_vector(material_slice_y1, [0, 1, 0]) - translated_material_slice_y2 = translate_by_vector(material_slice_y2, [0, -1, 0]) - augmented_material_y = merge_materials( - [augmented_material_x, translated_material_slice_y1, translated_material_slice_y2] - ) - - material_slice_z1 = filter_by_box(augmented_material_y, [-cutoff, -cutoff, 0], [1 + cutoff, 1 + cutoff, cutoff]) - material_slice_z2 = filter_by_box(augmented_material_y, [-cutoff, -cutoff, 1 - cutoff], [1 + cutoff, 1 + cutoff, 1]) - translated_material_slice_z1 = translate_by_vector(material_slice_z1, [0, 0, 1]) - translated_material_slice_z2 = translate_by_vector(material_slice_z2, [0, 0, -1]) - augmented_material = merge_materials( - [augmented_material_y, translated_material_slice_z1, translated_material_slice_z2] - ) +def augment_material_with_periodic_images(material: Material, cutoff: float = 0.1): + """ + Augment the material's dataset by adding atoms from periodic images near boundaries. + + Args: + material (Material): The material to augment. + cutoff (float): The cutoff value for filtering atoms near boundaries. + + Returns: + Tuple[Material, int]: The augmented material and the original count of atoms. + """ + original_count = len(material.basis.coordinates.values) + coordinates = np.array(material.basis.coordinates.values) + elements = np.array(material.basis.elements.values) + augmented_coords = [] + augmented_elems = [] + + for axis in range(3): + for direction in [-1, 1]: + translated_coords, translated_elems = filter_and_translate(coordinates, elements, axis, cutoff, direction) + augmented_coords.append(translated_coords) + augmented_elems.append(translated_elems) + + augmented_coords = np.vstack(augmented_coords).tolist() + augmented_elems = np.concatenate(augmented_elems).tolist() + augmented_material = material.clone() + + new_basis = material.basis.copy() + for i, coord in enumerate(augmented_coords): + new_basis.add_atom(augmented_elems[i], coord) + + augmented_material.basis = new_basis return augmented_material, original_count From e908fe6e5284ba5cefbc6cea96cfbae4f2b567d8 Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Wed, 28 Aug 2024 20:24:38 -0700 Subject: [PATCH 3/8] update: some fixes for tests to pass --- src/py/mat3ra/made/tools/analyze.py | 3 ++- src/py/mat3ra/made/tools/utils/__init__.py | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/py/mat3ra/made/tools/analyze.py b/src/py/mat3ra/made/tools/analyze.py index d3ae305f..afb3c41c 100644 --- a/src/py/mat3ra/made/tools/analyze.py +++ b/src/py/mat3ra/made/tools/analyze.py @@ -350,7 +350,7 @@ def shadowing_check(z: float, neighbors_indices: List[int], surface: SurfaceType ) -@decorator_handle_periodic_boundary_conditions(cutoff=3.0) +@decorator_handle_periodic_boundary_conditions(cutoff=0.1) def get_surface_atom_indices( material: Material, surface: SurfaceTypes = SurfaceTypes.TOP, shadowing_radius: float = 2.5, depth: float = 5 ) -> List[int]: @@ -417,6 +417,7 @@ def get_coordination_numbers( return coordination_numbers +# TODO: fix decorator removal of added atoms and uncomment @decorator_handle_periodic_boundary_conditions(cutoff=0.1) def get_undercoordinated_atom_indices( material: Material, diff --git a/src/py/mat3ra/made/tools/utils/__init__.py b/src/py/mat3ra/made/tools/utils/__init__.py index c3fd325d..392ee17b 100644 --- a/src/py/mat3ra/made/tools/utils/__init__.py +++ b/src/py/mat3ra/made/tools/utils/__init__.py @@ -113,15 +113,15 @@ def decorator_handle_periodic_boundary_conditions(cutoff): def decorator(func): @wraps(func) def wrapper(material, *args, **kwargs): - # Augment material with periodic images augmented_material, original_count = augment_material_with_periodic_images(material, cutoff) - - # Call the original function with augmented material result = func(augmented_material, *args, **kwargs) - # Filter results to include only original atoms if isinstance(result, list): result = [idx for idx in result if idx < original_count] + + if isinstance(result, list) and all(isinstance(coord, float) for coord in result): + result = [coordinate for coordinate in result if 0 <= coordinate <= 1] + return result return wrapper @@ -179,7 +179,7 @@ def augment_material_with_periodic_images(material: Material, cutoff: float = 0. augmented_elems = np.concatenate(augmented_elems).tolist() augmented_material = material.clone() - new_basis = material.basis.copy() + new_basis = augmented_material.basis.copy() for i, coord in enumerate(augmented_coords): new_basis.add_atom(augmented_elems[i], coord) From e7df9f42e7341fa266f3a5fd9883f9f18abb7f13 Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Thu, 29 Aug 2024 10:52:43 -0700 Subject: [PATCH 4/8] update: correctly handle diagonal cells --- src/py/mat3ra/made/tools/analyze.py | 1 - src/py/mat3ra/made/tools/utils/__init__.py | 13 ++++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/py/mat3ra/made/tools/analyze.py b/src/py/mat3ra/made/tools/analyze.py index afb3c41c..15f49ad6 100644 --- a/src/py/mat3ra/made/tools/analyze.py +++ b/src/py/mat3ra/made/tools/analyze.py @@ -417,7 +417,6 @@ def get_coordination_numbers( return coordination_numbers -# TODO: fix decorator removal of added atoms and uncomment @decorator_handle_periodic_boundary_conditions(cutoff=0.1) def get_undercoordinated_atom_indices( material: Material, diff --git a/src/py/mat3ra/made/tools/utils/__init__.py b/src/py/mat3ra/made/tools/utils/__init__.py index 392ee17b..4c3dbd0b 100644 --- a/src/py/mat3ra/made/tools/utils/__init__.py +++ b/src/py/mat3ra/made/tools/utils/__init__.py @@ -166,19 +166,18 @@ def augment_material_with_periodic_images(material: Material, cutoff: float = 0. original_count = len(material.basis.coordinates.values) coordinates = np.array(material.basis.coordinates.values) elements = np.array(material.basis.elements.values) - augmented_coords = [] - augmented_elems = [] + augmented_coords = coordinates.tolist() + augmented_elems = elements.tolist() for axis in range(3): for direction in [-1, 1]: translated_coords, translated_elems = filter_and_translate(coordinates, elements, axis, cutoff, direction) - augmented_coords.append(translated_coords) - augmented_elems.append(translated_elems) + augmented_coords.extend(translated_coords) + augmented_elems.extend(translated_elems) + coordinates = np.array(augmented_coords) + elements = np.array(augmented_elems) - augmented_coords = np.vstack(augmented_coords).tolist() - augmented_elems = np.concatenate(augmented_elems).tolist() augmented_material = material.clone() - new_basis = augmented_material.basis.copy() for i, coord in enumerate(augmented_coords): new_basis.add_atom(augmented_elems[i], coord) From cbc413163857657122006110501c44f1aafe7284 Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Thu, 29 Aug 2024 13:30:08 -0700 Subject: [PATCH 5/8] update: fix exessive after decorator --- src/py/mat3ra/made/tools/utils/__init__.py | 47 +++++++++++++--------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/src/py/mat3ra/made/tools/utils/__init__.py b/src/py/mat3ra/made/tools/utils/__init__.py index 4c3dbd0b..1ac833cc 100644 --- a/src/py/mat3ra/made/tools/utils/__init__.py +++ b/src/py/mat3ra/made/tools/utils/__init__.py @@ -3,6 +3,7 @@ import numpy as np from mat3ra.made.material import Material +from mat3ra.made.utils import ArrayWithIds from mat3ra.utils.matrix import convert_2x2_to_3x3 from ..third_party import PymatgenStructure @@ -110,18 +111,32 @@ def transform_coordinate_to_supercell( def decorator_handle_periodic_boundary_conditions(cutoff): + """ + Decorator to handle periodic boundary conditions. + + Copies atoms near boundaries within the cutoff distance beyond the opposite side of the cell + creating the effect of periodic boundary conditions for edge atoms. + + Results of the function are filtered to remove atoms or coordinates outside the original cell. + + Args: + cutoff (float): The cutoff distance for a border slice in crystal coordinates. + + Returns: + Callable: The decorated function. + """ + def decorator(func): @wraps(func) def wrapper(material, *args, **kwargs): - augmented_material, original_count = augment_material_with_periodic_images(material, cutoff) + augmented_material, last_id = augment_material_with_periodic_images(material, cutoff) result = func(augmented_material, *args, **kwargs) if isinstance(result, list): - result = [idx for idx in result if idx < original_count] - - if isinstance(result, list) and all(isinstance(coord, float) for coord in result): - result = [coordinate for coordinate in result if 0 <= coordinate <= 1] - + if all(isinstance(x, int) for x in result): + result = [id for id in result if id <= last_id] + elif all(isinstance(x, list) and len(x) == 3 for x in result): + result = [coord for coord in result if all(0 <= c < 1 for c in coord)] return result return wrapper @@ -163,24 +178,18 @@ def augment_material_with_periodic_images(material: Material, cutoff: float = 0. Returns: Tuple[Material, int]: The augmented material and the original count of atoms. """ - original_count = len(material.basis.coordinates.values) + last_id = material.basis.coordinates.ids[-1] coordinates = np.array(material.basis.coordinates.values) elements = np.array(material.basis.elements.values) - augmented_coords = coordinates.tolist() - augmented_elems = elements.tolist() + augmented_material = material.clone() + new_basis = augmented_material.basis.copy() for axis in range(3): for direction in [-1, 1]: translated_coords, translated_elems = filter_and_translate(coordinates, elements, axis, cutoff, direction) - augmented_coords.extend(translated_coords) - augmented_elems.extend(translated_elems) - coordinates = np.array(augmented_coords) - elements = np.array(augmented_elems) - - augmented_material = material.clone() - new_basis = augmented_material.basis.copy() - for i, coord in enumerate(augmented_coords): - new_basis.add_atom(augmented_elems[i], coord) + for coord, elem in zip(translated_coords, translated_elems): + if not any(np.allclose(coord, existing_coord) for existing_coord in new_basis.coordinates.values): + new_basis.add_atom(elem, coord) augmented_material.basis = new_basis - return augmented_material, original_count + return augmented_material, last_id From 499d8ae779d832bef2d0c9f4b4f281751ac74a8a Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Thu, 29 Aug 2024 20:09:36 -0700 Subject: [PATCH 6/8] update: add try for faulty nn --- src/py/mat3ra/made/tools/analyze.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/py/mat3ra/made/tools/analyze.py b/src/py/mat3ra/made/tools/analyze.py index 15f49ad6..a209f07c 100644 --- a/src/py/mat3ra/made/tools/analyze.py +++ b/src/py/mat3ra/made/tools/analyze.py @@ -300,8 +300,10 @@ def get_nearest_neighbors_atom_indices( site_index = len(structure.sites) - 1 remove_dummy_atom = True - - neighbors = voronoi_nn.get_nn_info(structure, site_index) + try: + neighbors = voronoi_nn.get_nn_info(structure, site_index) + except: + return None neighboring_atoms_pymatgen_ids = [n["site_index"] for n in neighbors] if remove_dummy_atom: structure.remove_sites([-1]) From bd996d5cb8eedaf191cd49506f3b37e4263c02ab Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Thu, 29 Aug 2024 20:09:55 -0700 Subject: [PATCH 7/8] update: don't add colliding atom --- src/py/mat3ra/made/basis.py | 12 ++++++++++-- src/py/mat3ra/made/tools/utils/__init__.py | 3 +-- src/py/mat3ra/made/utils.py | 17 +++++++++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/py/mat3ra/made/basis.py b/src/py/mat3ra/made/basis.py index da34c13c..21c043ec 100644 --- a/src/py/mat3ra/made/basis.py +++ b/src/py/mat3ra/made/basis.py @@ -6,7 +6,7 @@ from pydantic import BaseModel from .cell import Cell -from .utils import ArrayWithIds +from .utils import ArrayWithIds, get_overlapping_coordinates class Basis(RoundNumericValuesMixin, BaseModel): @@ -76,7 +76,15 @@ def to_crystal(self): self.coordinates.map_array_in_place(self.cell.convert_point_to_crystal) self.units = AtomicCoordinateUnits.crystal - def add_atom(self, element="Si", coordinate=[0.5, 0.5, 0.5]): + def add_atom(self, element="Si", coordinate=None, force=False): + if coordinate is None: + coordinate = [0, 0, 0] + if get_overlapping_coordinates(coordinate, self.coordinates.values, threshold=0.01): + if force: + print(f"Warning: Overlapping coordinates found for {coordinate}. Adding atom anyway.") + else: + print(f"Warning: Overlapping coordinates found for {coordinate}. Not adding atom.") + return self.elements.add_item(element) self.coordinates.add_item(coordinate) diff --git a/src/py/mat3ra/made/tools/utils/__init__.py b/src/py/mat3ra/made/tools/utils/__init__.py index 1ac833cc..964dbfcf 100644 --- a/src/py/mat3ra/made/tools/utils/__init__.py +++ b/src/py/mat3ra/made/tools/utils/__init__.py @@ -188,8 +188,7 @@ def augment_material_with_periodic_images(material: Material, cutoff: float = 0. for direction in [-1, 1]: translated_coords, translated_elems = filter_and_translate(coordinates, elements, axis, cutoff, direction) for coord, elem in zip(translated_coords, translated_elems): - if not any(np.allclose(coord, existing_coord) for existing_coord in new_basis.coordinates.values): - new_basis.add_atom(elem, coord) + new_basis.add_atom(elem, coord) augmented_material.basis = new_basis return augmented_material, last_id diff --git a/src/py/mat3ra/made/utils.py b/src/py/mat3ra/made/utils.py index 38ca10c3..cd8a7e33 100644 --- a/src/py/mat3ra/made/utils.py +++ b/src/py/mat3ra/made/utils.py @@ -58,6 +58,23 @@ def get_center_of_coordinates(coordinates: List[List[float]]) -> List[float]: return np.mean(np.array(coordinates), axis=0).tolist() +def get_overlapping_coordinates( + coordinate: List[float], coordinates: List[List[float]], threshold: float = 0.01 +) -> List[List[float]]: + """ + Find coordinates that are within a certain threshold of a given coordinate. + + Args: + coordinate (List[float]): The coordinate. + coordinates (List[List[float]]): The list of coordinates. + threshold (float): The threshold. + + Returns: + List[List[float]]: The list of overlapping coordinates. + """ + return [c for c in coordinates if np.linalg.norm(np.array(c) - np.array(coordinate)) < threshold] + + class ValueWithId(RoundNumericValuesMixin, BaseModel): id: int = 0 value: Any = None From 008264db4f44d0a1dc2ae00d64652710f5fa8968 Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Thu, 29 Aug 2024 20:18:22 -0700 Subject: [PATCH 8/8] chore: run lint fix --- src/py/mat3ra/made/tools/analyze.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/py/mat3ra/made/tools/analyze.py b/src/py/mat3ra/made/tools/analyze.py index a209f07c..1912a88a 100644 --- a/src/py/mat3ra/made/tools/analyze.py +++ b/src/py/mat3ra/made/tools/analyze.py @@ -1,13 +1,13 @@ from typing import Callable, List, Literal, Optional import numpy as np -from .utils import decorator_handle_periodic_boundary_conditions from scipy.spatial import cKDTree from ..material import Material from .build.passivation.enums import SurfaceTypes from .convert import decorator_convert_material_args_kwargs_to_atoms, to_pymatgen from .third_party import ASEAtoms, PymatgenIStructure, PymatgenVoronoiNN +from .utils import decorator_handle_periodic_boundary_conditions @decorator_convert_material_args_kwargs_to_atoms @@ -302,7 +302,7 @@ def get_nearest_neighbors_atom_indices( remove_dummy_atom = True try: neighbors = voronoi_nn.get_nn_info(structure, site_index) - except: + except ValueError: return None neighboring_atoms_pymatgen_ids = [n["site_index"] for n in neighbors] if remove_dummy_atom: