Moved functions around to circumvent a circular import
This commit is contained in:
parent
cedfd24bb3
commit
476f7167b4
1
.gitignore
vendored
1
.gitignore
vendored
@ -17,3 +17,4 @@ tmp/
|
|||||||
.traj.xtc_offsets.lock
|
.traj.xtc_offsets.lock
|
||||||
.traj.xtc_offsets.npz
|
.traj.xtc_offsets.npz
|
||||||
*.npy
|
*.npy
|
||||||
|
.venv/
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
import re
|
import re
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import numpy.typing as npt
|
|
||||||
from scipy.spatial import KDTree
|
|
||||||
|
|
||||||
from .pbc import pbc_diff, pbc_points
|
|
||||||
from .checksum import checksum
|
from .checksum import checksum
|
||||||
from .coordinates import CoordinateFrame
|
|
||||||
|
|
||||||
|
|
||||||
def compare_regex(str_list: list[str], exp: str) -> np.ndarray:
|
def compare_regex(str_list: list[str], exp: str) -> np.ndarray:
|
||||||
@ -176,95 +171,6 @@ class AtomSubset:
|
|||||||
return checksum(self.description)
|
return checksum(self.description)
|
||||||
|
|
||||||
|
|
||||||
def gyration_radius(position: CoordinateFrame) -> np.ndarray:
|
|
||||||
r"""
|
|
||||||
Calculates a list of all radii of gyration of all molecules given in the coordinate
|
|
||||||
frame, weighted with the masses of the individual atoms.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
position: Coordinate frame object
|
|
||||||
|
|
||||||
..math::
|
|
||||||
R_G = \left(\frac{\sum_{i=1}^{n} m_i |\vec{r_i}
|
|
||||||
- \vec{r_{COM}}|^2 }{\sum_{i=1}^{n} m_i }
|
|
||||||
\rigth)^{\frac{1}{2}}
|
|
||||||
"""
|
|
||||||
gyration_radii = np.array([])
|
|
||||||
|
|
||||||
for resid in np.unique(position.residue_ids):
|
|
||||||
pos = position.whole[position.residue_ids == resid]
|
|
||||||
mass = position.masses[position.residue_ids == resid][:, np.newaxis]
|
|
||||||
COM = 1 / mass.sum() * (mass * position).sum(axis=0)
|
|
||||||
r_sq = ((pbc_diff(pos, COM, pos.box.diagonal())) ** 2).sum(1)[:, np.newaxis]
|
|
||||||
g_radius = ((r_sq * mass).sum() / mass.sum()) ** 0.5
|
|
||||||
|
|
||||||
gyration_radii = np.append(gyration_radii, g_radius)
|
|
||||||
|
|
||||||
return gyration_radii
|
|
||||||
|
|
||||||
|
|
||||||
def layer_of_atoms(
|
|
||||||
atoms: CoordinateFrame,
|
|
||||||
thickness: float,
|
|
||||||
plane_normal: npt.ArrayLike,
|
|
||||||
plane_offset: Optional[npt.ArrayLike] = np.array([0, 0, 0]),
|
|
||||||
) -> np.array:
|
|
||||||
if plane_offset is None:
|
|
||||||
np.array([0, 0, 0])
|
|
||||||
atoms = atoms - plane_offset
|
|
||||||
distance = np.dot(atoms, plane_normal)
|
|
||||||
return np.abs(distance) <= thickness
|
|
||||||
|
|
||||||
|
|
||||||
def next_neighbors(
|
|
||||||
atoms: CoordinateFrame,
|
|
||||||
query_atoms: Optional[CoordinateFrame] = None,
|
|
||||||
number_of_neighbors: int = 1,
|
|
||||||
distance_upper_bound: float = np.inf,
|
|
||||||
distinct: bool = False,
|
|
||||||
**kwargs
|
|
||||||
) -> (np.ndarray, np.ndarray):
|
|
||||||
"""
|
|
||||||
Find the N next neighbors of a set of atoms.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
atoms:
|
|
||||||
The reference atoms and also the atoms which are queried if `query_atoms`
|
|
||||||
is net provided
|
|
||||||
query_atoms (opt.): If this is not None, these atoms will be queried
|
|
||||||
number_of_neighbors (int, opt.): Number of neighboring atoms to find
|
|
||||||
distance_upper_bound (float, opt.):
|
|
||||||
Upper bound of the distance between neighbors
|
|
||||||
distinct (bool, opt.):
|
|
||||||
If this is true, the atoms and query atoms are taken as distinct sets of
|
|
||||||
atoms
|
|
||||||
"""
|
|
||||||
dnn = 0
|
|
||||||
if query_atoms is None:
|
|
||||||
query_atoms = atoms
|
|
||||||
dnn = 1
|
|
||||||
elif not distinct:
|
|
||||||
dnn = 1
|
|
||||||
|
|
||||||
box = atoms.box
|
|
||||||
if np.all(np.diag(np.diag(box)) == box):
|
|
||||||
atoms = atoms % np.diag(box)
|
|
||||||
tree = KDTree(atoms, boxsize=np.diag(box))
|
|
||||||
distances, indices = tree.query(
|
|
||||||
query_atoms,
|
|
||||||
number_of_neighbors + dnn,
|
|
||||||
distance_upper_bound=distance_upper_bound,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
atoms_pbc, atoms_pbc_index = pbc_points(
|
|
||||||
query_atoms, box, thickness=distance_upper_bound + 0.1, index=True, **kwargs
|
|
||||||
)
|
|
||||||
tree = KDTree(atoms_pbc)
|
|
||||||
distances, indices = tree.query(
|
|
||||||
query_atoms,
|
|
||||||
number_of_neighbors + dnn,
|
|
||||||
distance_upper_bound=distance_upper_bound,
|
|
||||||
)
|
|
||||||
indices = atoms_pbc_index[indices]
|
|
||||||
|
|
||||||
return distances[:, dnn:], indices[:, dnn:]
|
|
||||||
|
@ -5,9 +5,10 @@ from typing import Optional, Callable
|
|||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import numpy.typing as npt
|
import numpy.typing as npt
|
||||||
|
from scipy.spatial import KDTree
|
||||||
|
|
||||||
from .atoms import AtomSubset
|
from .atoms import AtomSubset
|
||||||
from .pbc import whole, nojump, pbc_diff
|
from .pbc import whole, nojump, pbc_diff, pbc_points
|
||||||
from .utils import singledispatchmethod
|
from .utils import singledispatchmethod
|
||||||
from .checksum import checksum
|
from .checksum import checksum
|
||||||
|
|
||||||
@ -458,8 +459,8 @@ def pore_coordinates(
|
|||||||
@map_coordinates
|
@map_coordinates
|
||||||
def vectors(
|
def vectors(
|
||||||
frame: CoordinateFrame,
|
frame: CoordinateFrame,
|
||||||
atoms_indices_a: npt.ArrayLike[int],
|
atoms_indices_a: npt.ArrayLike,
|
||||||
atoms_indices_b: npt.ArrayLike[int],
|
atoms_indices_b: npt.ArrayLike,
|
||||||
normed: bool = False,
|
normed: bool = False,
|
||||||
) -> np.ndarray:
|
) -> np.ndarray:
|
||||||
"""
|
"""
|
||||||
@ -506,7 +507,7 @@ def vectors(
|
|||||||
|
|
||||||
@map_coordinates
|
@map_coordinates
|
||||||
def dipole_vector(
|
def dipole_vector(
|
||||||
frame: CoordinateFrame, atom_indices: npt.ArrayLike[int], normed: bool = None
|
frame: CoordinateFrame, atom_indices: npt.ArrayLike, normed: bool = None
|
||||||
) -> np.ndarray:
|
) -> np.ndarray:
|
||||||
coords = frame.whole[atom_indices]
|
coords = frame.whole[atom_indices]
|
||||||
res_ids = frame.residue_ids[atom_indices]
|
res_ids = frame.residue_ids[atom_indices]
|
||||||
@ -524,7 +525,7 @@ def dipole_vector(
|
|||||||
@map_coordinates
|
@map_coordinates
|
||||||
def sum_dipole_vector(
|
def sum_dipole_vector(
|
||||||
coordinates: CoordinateFrame,
|
coordinates: CoordinateFrame,
|
||||||
atom_indices: npt.ArrayLike[int],
|
atom_indices: npt.ArrayLike,
|
||||||
normed: bool = True,
|
normed: bool = True,
|
||||||
) -> np.ndarray:
|
) -> np.ndarray:
|
||||||
coords = coordinates.whole[atom_indices]
|
coords = coordinates.whole[atom_indices]
|
||||||
@ -538,9 +539,9 @@ def sum_dipole_vector(
|
|||||||
@map_coordinates
|
@map_coordinates
|
||||||
def normal_vectors(
|
def normal_vectors(
|
||||||
frame: CoordinateFrame,
|
frame: CoordinateFrame,
|
||||||
atom_indices_a: npt.ArrayLike[int],
|
atom_indices_a: npt.ArrayLike,
|
||||||
atom_indices_b: npt.ArrayLike[int],
|
atom_indices_b: npt.ArrayLike,
|
||||||
atom_indices_c: npt.ArrayLike[int],
|
atom_indices_c: npt.ArrayLike,
|
||||||
normed: bool = True,
|
normed: bool = True,
|
||||||
) -> np.ndarray:
|
) -> np.ndarray:
|
||||||
coords_a = frame[atom_indices_a]
|
coords_a = frame[atom_indices_a]
|
||||||
@ -580,3 +581,70 @@ def cylindrical_coordinates(
|
|||||||
radius = (x**2 + y**2) ** 0.5
|
radius = (x**2 + y**2) ** 0.5
|
||||||
phi = np.arctan2(y, x)
|
phi = np.arctan2(y, x)
|
||||||
return np.array([radius, phi, z]).T
|
return np.array([radius, phi, z]).T
|
||||||
|
|
||||||
|
|
||||||
|
def layer_of_atoms(
|
||||||
|
atoms: CoordinateFrame,
|
||||||
|
thickness: float,
|
||||||
|
plane_normal: npt.ArrayLike,
|
||||||
|
plane_offset: Optional[npt.ArrayLike] = np.array([0, 0, 0]),
|
||||||
|
) -> np.array:
|
||||||
|
if plane_offset is None:
|
||||||
|
np.array([0, 0, 0])
|
||||||
|
atoms = atoms - plane_offset
|
||||||
|
distance = np.dot(atoms, plane_normal)
|
||||||
|
return np.abs(distance) <= thickness
|
||||||
|
|
||||||
|
|
||||||
|
def next_neighbors(
|
||||||
|
atoms: CoordinateFrame,
|
||||||
|
query_atoms: Optional[CoordinateFrame] = None,
|
||||||
|
number_of_neighbors: int = 1,
|
||||||
|
distance_upper_bound: float = np.inf,
|
||||||
|
distinct: bool = False,
|
||||||
|
**kwargs
|
||||||
|
) -> (np.ndarray, np.ndarray):
|
||||||
|
"""
|
||||||
|
Find the N next neighbors of a set of atoms.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
atoms:
|
||||||
|
The reference atoms and also the atoms which are queried if `query_atoms`
|
||||||
|
is net provided
|
||||||
|
query_atoms (opt.): If this is not None, these atoms will be queried
|
||||||
|
number_of_neighbors (int, opt.): Number of neighboring atoms to find
|
||||||
|
distance_upper_bound (float, opt.):
|
||||||
|
Upper bound of the distance between neighbors
|
||||||
|
distinct (bool, opt.):
|
||||||
|
If this is true, the atoms and query atoms are taken as distinct sets of
|
||||||
|
atoms
|
||||||
|
"""
|
||||||
|
dnn = 0
|
||||||
|
if query_atoms is None:
|
||||||
|
query_atoms = atoms
|
||||||
|
dnn = 1
|
||||||
|
elif not distinct:
|
||||||
|
dnn = 1
|
||||||
|
|
||||||
|
box = atoms.box
|
||||||
|
if np.all(np.diag(np.diag(box)) == box):
|
||||||
|
atoms = atoms % np.diag(box)
|
||||||
|
tree = KDTree(atoms, boxsize=np.diag(box))
|
||||||
|
distances, indices = tree.query(
|
||||||
|
query_atoms,
|
||||||
|
number_of_neighbors + dnn,
|
||||||
|
distance_upper_bound=distance_upper_bound,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
atoms_pbc, atoms_pbc_index = pbc_points(
|
||||||
|
query_atoms, box, thickness=distance_upper_bound + 0.1, index=True, **kwargs
|
||||||
|
)
|
||||||
|
tree = KDTree(atoms_pbc)
|
||||||
|
distances, indices = tree.query(
|
||||||
|
query_atoms,
|
||||||
|
number_of_neighbors + dnn,
|
||||||
|
distance_upper_bound=distance_upper_bound,
|
||||||
|
)
|
||||||
|
indices = atoms_pbc_index[indices]
|
||||||
|
|
||||||
|
return distances[:, dnn:], indices[:, dnn:]
|
||||||
|
@ -4,8 +4,13 @@ from scipy import spatial
|
|||||||
from scipy.spatial import KDTree
|
from scipy.spatial import KDTree
|
||||||
from scipy.sparse.csgraph import connected_components
|
from scipy.sparse.csgraph import connected_components
|
||||||
|
|
||||||
from .coordinates import rotate_axis, polar_coordinates, Coordinates, CoordinateFrame
|
from .coordinates import (
|
||||||
from .atoms import next_neighbors
|
rotate_axis,
|
||||||
|
polar_coordinates,
|
||||||
|
Coordinates,
|
||||||
|
CoordinateFrame,
|
||||||
|
next_neighbors,
|
||||||
|
)
|
||||||
from .autosave import autosave_data
|
from .autosave import autosave_data
|
||||||
from .utils import runningmean
|
from .utils import runningmean
|
||||||
from .pbc import pbc_diff, pbc_points
|
from .pbc import pbc_diff, pbc_points
|
||||||
@ -455,3 +460,30 @@ def calc_cluster_sizes(frame, r_max=0.35):
|
|||||||
for i in range(0, np.max(labels) + 1):
|
for i in range(0, np.max(labels) + 1):
|
||||||
cluster_sizes.append(np.sum(labels == i))
|
cluster_sizes.append(np.sum(labels == i))
|
||||||
return np.array(cluster_sizes).flatten()
|
return np.array(cluster_sizes).flatten()
|
||||||
|
|
||||||
|
|
||||||
|
def gyration_radius(position: CoordinateFrame) -> np.ndarray:
|
||||||
|
r"""
|
||||||
|
Calculates a list of all radii of gyration of all molecules given in the coordinate
|
||||||
|
frame, weighted with the masses of the individual atoms.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
position: Coordinate frame object
|
||||||
|
|
||||||
|
..math::
|
||||||
|
R_G = \left(\frac{\sum_{i=1}^{n} m_i |\vec{r_i}
|
||||||
|
- \vec{r_{COM}}|^2 }{\sum_{i=1}^{n} m_i }
|
||||||
|
\rigth)^{\frac{1}{2}}
|
||||||
|
"""
|
||||||
|
gyration_radii = np.array([])
|
||||||
|
|
||||||
|
for resid in np.unique(position.residue_ids):
|
||||||
|
pos = position.whole[position.residue_ids == resid]
|
||||||
|
mass = position.masses[position.residue_ids == resid][:, np.newaxis]
|
||||||
|
COM = 1 / mass.sum() * (mass * position).sum(axis=0)
|
||||||
|
r_sq = ((pbc_diff(pos, COM, pos.box.diagonal())) ** 2).sum(1)[:, np.newaxis]
|
||||||
|
g_radius = ((r_sq * mass).sum() / mass.sum()) ** 0.5
|
||||||
|
|
||||||
|
gyration_radii = np.append(gyration_radii, g_radius)
|
||||||
|
|
||||||
|
return gyration_radii
|
||||||
|
Loading…
Reference in New Issue
Block a user