Added type hints and removed number_of_next_neighbors
This commit is contained in:
parent
b39dd3c45f
commit
4f17cfe876
@ -1,9 +1,17 @@
|
|||||||
|
from typing import Tuple, Callable
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from numpy.typing import ArrayLike, NDArray
|
||||||
|
import pandas as pd
|
||||||
|
from scipy import sparse
|
||||||
from scipy.spatial import KDTree
|
from scipy.spatial import KDTree
|
||||||
from scipy.special import sph_harm
|
from scipy.special import sph_harm
|
||||||
|
|
||||||
|
from mdevaluate.coordinates import CoordinateFrame, Coordinates
|
||||||
|
from mdevaluate.pbc import pbc_points
|
||||||
|
|
||||||
def a_ij(atoms, N=4, l=3):
|
|
||||||
|
def a_ij(atoms: ArrayLike, N: int = 4, l: int = 3) -> tuple[NDArray, NDArray]:
|
||||||
tree = KDTree(atoms)
|
tree = KDTree(atoms)
|
||||||
|
|
||||||
dist, indices = tree.query(atoms, N + 1)
|
dist, indices = tree.query(atoms, N + 1)
|
||||||
@ -30,13 +38,9 @@ def a_ij(atoms, N=4, l=3):
|
|||||||
return np.real(aij), indices
|
return np.real(aij), indices
|
||||||
|
|
||||||
|
|
||||||
def number_of_neighbors(atoms):
|
def classify_ice(
|
||||||
tree = KDTree(atoms)
|
aij: NDArray, indices: NDArray, neighbors: NDArray, indexSOL: NDArray
|
||||||
dist, _ = tree.query(atoms, 10, distance_upper_bound=0.35)
|
) -> NDArray:
|
||||||
return np.array([len(distance[distance < 0.4]) - 1 for distance in dist])
|
|
||||||
|
|
||||||
|
|
||||||
def classify_ice(aij, indices, neighbors, indexSOL):
|
|
||||||
staggerdBonds = np.sum(aij <= -0.8, axis=1)
|
staggerdBonds = np.sum(aij <= -0.8, axis=1)
|
||||||
eclipsedBonds = np.sum((aij >= -0.35) & (aij <= 0.25), axis=1)
|
eclipsedBonds = np.sum((aij >= -0.35) & (aij <= 0.25), axis=1)
|
||||||
|
|
||||||
@ -67,7 +71,7 @@ def classify_ice(aij, indices, neighbors, indexSOL):
|
|||||||
return iceTypes
|
return iceTypes
|
||||||
|
|
||||||
|
|
||||||
def ice_parts(iceTypes):
|
def count_ice_types(iceTypes: NDArray) -> NDArray:
|
||||||
cubic = len(iceTypes[iceTypes == 0])
|
cubic = len(iceTypes[iceTypes == 0])
|
||||||
hexagonal = len(iceTypes[iceTypes == 1])
|
hexagonal = len(iceTypes[iceTypes == 1])
|
||||||
interface = len(iceTypes[iceTypes == 2])
|
interface = len(iceTypes[iceTypes == 2])
|
||||||
@ -77,3 +81,119 @@ def ice_parts(iceTypes):
|
|||||||
return np.array(
|
return np.array(
|
||||||
[cubic, hexagonal, interface, clathrate, clathrate_interface, liquid]
|
[cubic, hexagonal, interface, clathrate, clathrate_interface, liquid]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def selector_ice(
|
||||||
|
start_frame: CoordinateFrame,
|
||||||
|
traj: Coordinates,
|
||||||
|
chosen_ice_types: ArrayLike,
|
||||||
|
combined: bool = True,
|
||||||
|
) -> NDArray:
|
||||||
|
oxygen = traj.subset(atom_name="OW")
|
||||||
|
atoms = oxygen[start_frame.step]
|
||||||
|
atoms = atoms % np.diag(atoms.box)
|
||||||
|
atoms_PBC = pbc_points(atoms, thickness=1)
|
||||||
|
aij, indices = a_ij(atoms_PBC)
|
||||||
|
tree = KDTree(atoms_PBC)
|
||||||
|
neighbors = tree.query_ball_point(atoms_PBC, 0.35, return_length=True)
|
||||||
|
index_SOL = atoms_PBC.tolist().index(atoms[0].tolist())
|
||||||
|
index_SOL = np.arange(index_SOL, index_SOL + len(atoms))
|
||||||
|
ice_Types = classify_ice(aij, indices, neighbors, index_SOL)
|
||||||
|
index = []
|
||||||
|
if combined is True:
|
||||||
|
for i, ice_Type in enumerate(ice_Types):
|
||||||
|
if ice_Type in chosen_ice_types:
|
||||||
|
index.append(i)
|
||||||
|
else:
|
||||||
|
for entry in chosen_ice_types:
|
||||||
|
index_entry = []
|
||||||
|
for i, ice_Type in enumerate(ice_Types):
|
||||||
|
if ice_Type == entry:
|
||||||
|
index_entry.append(i)
|
||||||
|
index.append(np.array(index_entry))
|
||||||
|
return np.array(index)
|
||||||
|
|
||||||
|
|
||||||
|
def ice_types(trajectory: Coordinates, segments: int = 10000) -> pd.DataFrame:
|
||||||
|
def ice_types_distribution(frame: CoordinateFrame, selector: Callable) -> NDArray:
|
||||||
|
atoms_PBC = pbc_points(frame, thickness=1)
|
||||||
|
aij, indices = a_ij(atoms_PBC)
|
||||||
|
tree = KDTree(atoms_PBC)
|
||||||
|
neighbors = tree.query_ball_point(atoms_PBC, 0.35, return_length=True)
|
||||||
|
index = selector(frame, atoms_PBC)
|
||||||
|
ice_types_data = classify_ice(aij, indices, neighbors, index)
|
||||||
|
ice_parts_data = count_ice_types(ice_types_data)
|
||||||
|
return ice_parts_data
|
||||||
|
|
||||||
|
def selector(frame: CoordinateFrame, atoms_PBC: ArrayLike) -> NDArray:
|
||||||
|
atoms_SOL = traj.subset(residue_name="SOL")[frame.step]
|
||||||
|
index = atoms_PBC.tolist().index(atoms_SOL[0].tolist())
|
||||||
|
index = np.arange(index, index + len(atoms_SOL))
|
||||||
|
return np.array(index)
|
||||||
|
|
||||||
|
traj = trajectory.subset(atom_name="OW")
|
||||||
|
|
||||||
|
frame_indices = np.unique(np.int_(np.linspace(0, len(traj) - 1, num=segments)))
|
||||||
|
|
||||||
|
result = np.array(
|
||||||
|
[
|
||||||
|
[
|
||||||
|
traj[frame_index].time,
|
||||||
|
*ice_types_distribution(traj[frame_index], selector),
|
||||||
|
]
|
||||||
|
for frame_index in frame_indices
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
return pd.DataFrame(
|
||||||
|
{
|
||||||
|
"time": result[:, 0],
|
||||||
|
"cubic": result[:, 1],
|
||||||
|
"hexagonal": result[:, 2],
|
||||||
|
"ice_interface": result[:, 3],
|
||||||
|
"clathrate": result[:, 4],
|
||||||
|
"clathrate_interface": result[:, 5],
|
||||||
|
"liquid": result[:, 6],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def ice_clusters_traj(
|
||||||
|
traj: Coordinates, segments: int = 10000, skip: float = 0.1
|
||||||
|
) -> list:
|
||||||
|
def ice_clusters(frame: CoordinateFrame, traj: Coordinates) -> Tuple[float, list]:
|
||||||
|
selection = selector_ice(frame, traj, [0, 1, 2])
|
||||||
|
if len(selection) == 0:
|
||||||
|
return frame.time, []
|
||||||
|
else:
|
||||||
|
ice = frame[selection]
|
||||||
|
ice_PBC, indices_PBC = pbc_points(
|
||||||
|
ice, box=frame.box, thickness=0.5, index=True
|
||||||
|
)
|
||||||
|
ice_tree = KDTree(ice_PBC)
|
||||||
|
ice_matrix = ice_tree.sparse_distance_matrix(
|
||||||
|
ice_tree, 0.35, output_type="ndarray"
|
||||||
|
)
|
||||||
|
new_ice_matrix = np.zeros((len(ice), len(ice)))
|
||||||
|
for entry in ice_matrix:
|
||||||
|
if entry[2] > 0:
|
||||||
|
new_ice_matrix[indices_PBC[entry[0]], indices_PBC[entry[1]]] = 1
|
||||||
|
n_components, labels = sparse.csgraph.connected_components(
|
||||||
|
new_ice_matrix, directed=False
|
||||||
|
)
|
||||||
|
clusters = []
|
||||||
|
selection = np.array(selection)
|
||||||
|
for i in range(0, np.max(labels) + 1):
|
||||||
|
if len(ice[labels == i]) > 1:
|
||||||
|
clusters.append(
|
||||||
|
list(zip(selection[labels == i], ice[labels == i].tolist()))
|
||||||
|
)
|
||||||
|
return frame.time, clusters
|
||||||
|
|
||||||
|
frame_indices = np.unique(
|
||||||
|
np.int_(np.linspace(len(traj) * skip, len(traj) - 1, num=segments))
|
||||||
|
)
|
||||||
|
all_clusters = [
|
||||||
|
ice_clusters(traj[frame_index], traj) for frame_index in frame_indices
|
||||||
|
]
|
||||||
|
return all_clusters
|
||||||
|
Loading…
Reference in New Issue
Block a user