diff --git a/package/CHANGELOG b/package/CHANGELOG index 08234a6cb6e..93524527cd4 100644 --- a/package/CHANGELOG +++ b/package/CHANGELOG @@ -20,7 +20,8 @@ The rules for this file: Enhancements - + * Modified around selections to work with KDTree and periodic boundary + conditions. Should reduce memory usage (#974 PR #2022) * Modified topology.guessers.guess_bonds to automatically select the fastest method for guessing bonds using lib.distance.self_capped_distance (PR # 2006) diff --git a/package/MDAnalysis/core/selection.py b/package/MDAnalysis/core/selection.py index bc4a256e20e..4532ac854a7 100644 --- a/package/MDAnalysis/core/selection.py +++ b/package/MDAnalysis/core/selection.py @@ -243,9 +243,6 @@ def __init__(self): self.apply = self._apply_distmat self.periodic = flags['use_periodic_selections'] - # KDTree doesn't support periodic - if self.periodic: - self.apply = self._apply_distmat def validate_dimensions(self, dimensions): r"""Check if the system is periodic in all three-dimensions. @@ -282,6 +279,9 @@ def _apply_KDTree(self, group): # All atoms in group that aren't in sel sys = group[~np.in1d(group.indices, sel.indices)] + if not sys: + return sys[[]] + box = self.validate_dimensions(group.dimensions) cut = self.cutoff if box is not None else None @@ -321,7 +321,8 @@ def _apply_KDTree(self, group): """ sel = self.sel.apply(group) box = self.validate_dimensions(group.dimensions) - ref = sel.center_of_geometry(pbc=self.periodic) + periodic = box is not None + ref = sel.center_of_geometry(pbc=periodic) kdtree = PeriodicKDTree(box=box) cutoff = self.exRadius if box is not None else None @@ -363,7 +364,8 @@ def _apply_KDTree(self, group): """ sel = self.sel.apply(group) box = self.validate_dimensions(group.dimensions) - ref = sel.center_of_geometry(pbc=self.periodic) + periodic = box is not None + ref = sel.center_of_geometry(pbc=periodic) cut = self.cutoff if box is not None else None kdtree = PeriodicKDTree(box=box) @@ -483,7 +485,7 @@ def __init__(self, parser, tokens): self.cutoff = float(tokens.popleft()) def _apply_KDTree(self, group): - box = group.dimensions if self.periodic else None + box = self.validate_dimensions(group.dimensions) kdtree = PeriodicKDTree(box=box) cut = self.cutoff if box is not None else None kdtree.set_coords(group.positions, cutoff=cut) @@ -496,7 +498,7 @@ def _apply_distmat(self, group): ref_coor = self.ref[np.newaxis, ...] ref_coor = np.asarray(ref_coor, dtype=np.float32) - box = group.dimensions if self.periodic else None + box = self.validate_dimensions(group.dimensions) dist = distances.distance_array(group.positions, ref_coor, box) mask = (dist <= self.cutoff).any(axis=1)