Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package/AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ Chronological list of authors
- Harshit Gajjela
- Kunj Sinha
- Ayush Agarwal
- Parth Uppal

External code
-------------
Expand Down
1 change: 1 addition & 0 deletions package/CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Enhancements
* Added new function `MDAnalysis.fetch.from_PDB` to download structure files from wwPDB
using `pooch` as optional dependency (Issue #4907, PR #4943)
* Added benchmarks for package.MDAnalysis.analysis.msd.EinsteinMSD (PR #5277)
* Reduces duplication of code in _apply() function (Issue #5247, PR #5294)
Comment thread
jeremyleung521 marked this conversation as resolved.
Outdated
* Improved performance of `AtomGroup.wrap()` with compounds (PR #5220)
* Adds support for parsing `.tpr` files produced by GROMACS 2026.0
* Enables parallelization for analysis.diffusionmap.DistanceMatrix
Expand Down
79 changes: 20 additions & 59 deletions package/MDAnalysis/core/selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,19 @@ def __init__(self, parser, tokens):
def apply(self, *args, **kwargs):
return self._apply(*args, **kwargs).asunique(sorted=self.parser.sorted)

def _apply_match_by_resnames(self, group, target_resnames):
"""Helper function to select atoms based on residue name matches in the topology."""
resnames = group.universe._topology.resnames
nmidx = resnames.nmidx[group.resindices]

matches = [
ix
for (nm, ix) in resnames.namedict.items()
if nm in target_resnames
]

return group[np.isin(nmidx, matches)]


class AllSelection(Selection):
token = "all"
Expand Down Expand Up @@ -1193,17 +1206,7 @@ class ProteinSelection(Selection):
}

def _apply(self, group):
resname_attr = group.universe._topology.resnames
# which values in resname attr are in prot_res?
matches = [
ix
for (nm, ix) in resname_attr.namedict.items()
if nm in self.prot_res
]
# index of each atom's resname
nmidx = resname_attr.nmidx[group.resindices]
# intersect atom's resname index and matches to prot_res
return group[np.isin(nmidx, matches)]
return self._apply_match_by_resnames(group, self.prot_res)


class NucleicSelection(Selection):
Expand Down Expand Up @@ -1263,15 +1266,7 @@ class NucleicSelection(Selection):
}

def _apply(self, group):
resnames = group.universe._topology.resnames
nmidx = resnames.nmidx[group.resindices]

matches = [
ix for (nm, ix) in resnames.namedict.items() if nm in self.nucl_res
]
mask = np.isin(nmidx, matches)

return group[mask]
return self._apply_match_by_resnames(group, self.nucl_res)


class WaterSelection(Selection):
Expand Down Expand Up @@ -1308,17 +1303,7 @@ class WaterSelection(Selection):
}

def _apply(self, group):
resnames = group.universe._topology.resnames
nmidx = resnames.nmidx[group.resindices]

matches = [
ix
for (nm, ix) in resnames.namedict.items()
if nm in self.water_res
]
mask = np.isin(nmidx, matches)

return group[mask]
return self._apply_match_by_resnames(group, self.water_res)


class BackboneSelection(ProteinSelection):
Expand Down Expand Up @@ -1350,13 +1335,7 @@ def _apply(self, group):
group = group[np.isin(nmidx, name_matches)]

# filter by resnames
resname_matches = [
ix for (nm, ix) in resnames.namedict.items() if nm in self.prot_res
]
nmidx = resnames.nmidx[group.resindices]
group = group[np.isin(nmidx, resname_matches)]

return group.unique
return self._apply_match_by_resnames(group, self.prot_res).unique


class NucleicBackboneSelection(NucleicSelection):
Expand Down Expand Up @@ -1388,13 +1367,7 @@ def _apply(self, group):
group = group[np.isin(nmidx, name_matches)]

# filter by resnames
resname_matches = [
ix for (nm, ix) in resnames.namedict.items() if nm in self.nucl_res
]
nmidx = resnames.nmidx[group.resindices]
group = group[np.isin(nmidx, resname_matches)]

return group.unique
return self._apply_match_by_resnames(group, self.nucl_res).unique


class BaseSelection(NucleicSelection):
Expand Down Expand Up @@ -1445,13 +1418,7 @@ def _apply(self, group):
group = group[np.isin(nmidx, name_matches)]

# filter by resnames
resname_matches = [
ix for (nm, ix) in resnames.namedict.items() if nm in self.nucl_res
]
nmidx = resnames.nmidx[group.resindices]
group = group[np.isin(nmidx, resname_matches)]

return group.unique
return self._apply_match_by_resnames(group, self.nucl_res).unique


class NucleicSugarSelection(NucleicSelection):
Expand Down Expand Up @@ -1480,13 +1447,7 @@ def _apply(self, group):
group = group[np.isin(nmidx, name_matches)]

# filter by resnames
resname_matches = [
ix for (nm, ix) in resnames.namedict.items() if nm in self.nucl_res
]
nmidx = resnames.nmidx[group.resindices]
group = group[np.isin(nmidx, resname_matches)]

return group.unique
return self._apply_match_by_resnames(group, self.nucl_res).unique


class PropertySelection(Selection):
Expand Down
Loading