From b5406caff4563abefc51fdc72867af31e2214b33 Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Tue, 27 Aug 2024 20:24:11 -0700 Subject: [PATCH 1/4] update: add local z extremum search --- src/py/mat3ra/made/tools/analyze.py | 41 +++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/py/mat3ra/made/tools/analyze.py b/src/py/mat3ra/made/tools/analyze.py index 889b6a88..3930c6e7 100644 --- a/src/py/mat3ra/made/tools/analyze.py +++ b/src/py/mat3ra/made/tools/analyze.py @@ -339,6 +339,47 @@ def get_atomic_coordinates_extremum( return getattr(np, extremum)(values) +def get_local_extremum_atom_index( + material: Material, + coordinate: List[float], + extremum: Literal["max", "min"] = "max", + vicinity: float = 1.0, + use_cartesian_coordinates: bool = False, +) -> int: + """ + Return the id of the atom with the minimum or maximum z-coordinate + within a certain vicinity of a given (x, y) coordinate. + + Args: + material (Material): Material object. + coordinate (List[float]): (x, y, z) coordinate to find the local extremum. + extremum (str): "min" or "max". + vicinity (float): Radius of the vicinity. + use_cartesian_coordinates (bool): Whether to use Cartesian coordinates. + + Returns: + int: id of the atom with the minimum or maximum z-coordinate. + """ + new_material = material.clone() + if use_cartesian_coordinates: + new_material.to_cartesian() + else: + new_material.to_crystal() + vicinity = vicinity / new_material.lattice.a + coordinates = np.array(new_material.basis.coordinates.values) + ids = np.array(new_material.basis.coordinates.ids) + tree = cKDTree(coordinates[:, :2]) + indices = tree.query_ball_point(coordinate[:2], vicinity) + z_values = [(id, coord[2]) for id, coord in zip(ids[indices], coordinates[indices])] + + if extremum == "max": + extremum_z_atom = max(z_values, key=lambda item: item[1]) + else: + extremum_z_atom = min(z_values, key=lambda item: item[1]) + + return extremum_z_atom[0] + + def height_check(z: float, z_extremum: float, depth: float, surface: SurfaceTypes): return (z >= z_extremum - depth) if surface == SurfaceTypes.TOP else (z <= z_extremum + depth) From e76329412cc101bc4f3dd2610d5c37f6d768a659 Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Tue, 27 Aug 2024 20:30:17 -0700 Subject: [PATCH 2/4] update: correctly handle cartesian coordinates --- src/py/mat3ra/made/tools/analyze.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/py/mat3ra/made/tools/analyze.py b/src/py/mat3ra/made/tools/analyze.py index 3930c6e7..61aaee0d 100644 --- a/src/py/mat3ra/made/tools/analyze.py +++ b/src/py/mat3ra/made/tools/analyze.py @@ -354,18 +354,17 @@ def get_local_extremum_atom_index( material (Material): Material object. coordinate (List[float]): (x, y, z) coordinate to find the local extremum. extremum (str): "min" or "max". - vicinity (float): Radius of the vicinity. + vicinity (float): Radius of the vicinity, in Angstroms. use_cartesian_coordinates (bool): Whether to use Cartesian coordinates. Returns: int: id of the atom with the minimum or maximum z-coordinate. """ new_material = material.clone() - if use_cartesian_coordinates: - new_material.to_cartesian() - else: - new_material.to_crystal() - vicinity = vicinity / new_material.lattice.a + new_material.to_cartesian() + if not use_cartesian_coordinates: + coordinate = new_material.basis.cell.convert_point_to_cartesian(coordinate) + coordinates = np.array(new_material.basis.coordinates.values) ids = np.array(new_material.basis.coordinates.ids) tree = cKDTree(coordinates[:, :2]) From 821e506557660715924d220ff3c750b9537141a7 Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Tue, 10 Sep 2024 17:51:57 -0700 Subject: [PATCH 3/4] chore: small adjustment --- src/py/mat3ra/made/tools/analyze.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/py/mat3ra/made/tools/analyze.py b/src/py/mat3ra/made/tools/analyze.py index 96c943de..4f08d659 100644 --- a/src/py/mat3ra/made/tools/analyze.py +++ b/src/py/mat3ra/made/tools/analyze.py @@ -358,6 +358,7 @@ def is_height_within_limits(z: float, z_extremum: float, depth: float, surface: bool: True if the height is within the limits, False otherwise. """ + def height_check(z: float, z_extremum: float, depth: float, surface: SurfaceTypes): return (z >= z_extremum - depth) if surface == SurfaceTypes.TOP else (z <= z_extremum + depth) @@ -486,7 +487,7 @@ def get_local_extremum_atom_index( Args: material (Material): Material object. - coordinate (List[float]): (x, y, z) coordinate to find the local extremum. + coordinate (List[float]): (x, y, z) coordinate to find the local extremum atom index for. extremum (str): "min" or "max". vicinity (float): Radius of the vicinity, in Angstroms. use_cartesian_coordinates (bool): Whether to use Cartesian coordinates. From 8ed8cea6c0a379e05609ceb1a7548fa3e02efd34 Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Tue, 10 Sep 2024 18:02:03 -0700 Subject: [PATCH 4/4] update: a fix from merging --- src/py/mat3ra/made/tools/analyze.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/py/mat3ra/made/tools/analyze.py b/src/py/mat3ra/made/tools/analyze.py index 4f08d659..ebf51a9f 100644 --- a/src/py/mat3ra/made/tools/analyze.py +++ b/src/py/mat3ra/made/tools/analyze.py @@ -357,9 +357,6 @@ def is_height_within_limits(z: float, z_extremum: float, depth: float, surface: Returns: bool: True if the height is within the limits, False otherwise. """ - - -def height_check(z: float, z_extremum: float, depth: float, surface: SurfaceTypes): return (z >= z_extremum - depth) if surface == SurfaceTypes.TOP else (z <= z_extremum + depth)