From 2b2d497fd5744440bb93259b290ae777473d337b Mon Sep 17 00:00:00 2001 From: zhiyiwu Date: Sun, 9 Feb 2020 17:41:37 +0000 Subject: [PATCH 1/3] Replace the distance search of finding hydrogens with a dictionary lookup --- .../analysis/hbonds/wbridge_analysis.py | 45 +++++++++++++++---- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/package/MDAnalysis/analysis/hbonds/wbridge_analysis.py b/package/MDAnalysis/analysis/hbonds/wbridge_analysis.py index 8a611364896..5413f7522fb 100644 --- a/package/MDAnalysis/analysis/hbonds/wbridge_analysis.py +++ b/package/MDAnalysis/analysis/hbonds/wbridge_analysis.py @@ -820,6 +820,18 @@ def _log_parameters(self): logger.info("WaterBridgeAnalysis: force field %s to guess donor and \ acceptor names", self.forcefield) + def _build_residue_dict(self, selection): + # Build the residue_dict where the key is the residue name + # The content is a dictionary where hydrogen bond donor heavy atom names is the key + # The content is the hydrogen bond donor hydrogen atom names + atom_group = self.u.select_atoms(selection) + for residue in atom_group.residues: + if not residue.resname in self._residue_dict: + self._residue_dict[residue.resname] = defaultdict(set) + for atom in residue.atoms: + if atom.name in self.donors: + self._residue_dict[residue.resname][atom.name].update(self._get_bonded_hydrogens(atom).names) + def _update_selection(self): self._s1_donors = [] self._s1_h_donors = {} @@ -861,9 +873,12 @@ def _update_selection(self): if self.selection1_type in ('donor', 'both'): self._s1_donors = self.u.atoms[self._s1].select_atoms( 'name {0}'.format(' '.join(self.donors))).ix - for i, atom_ix in enumerate(self._s1_donors): - tmp = self._get_bonded_hydrogens(self.u.atoms[atom_ix]).ix - for atom in tmp: + for atom_ix in self._s1_donors: + atom = self.u.atoms[atom_ix] + residue = atom.residue + hydrogens = residue.atoms.select_atoms('name {0}'.format( + ' '.join(self._residue_dict[residue.resname][atom.name]))).ix + for atom in hydrogens: self._s1_h_donors[atom] = atom_ix self._s1_donors_h[atom_ix].append(atom) self.logger_debug("Selection 1 donors: {0}".format(len(self._s1_donors))) @@ -882,9 +897,12 @@ def _update_selection(self): if self.selection1_type in ('acceptor', 'both'): self._s2_donors = self.u.atoms[self._s2].select_atoms( 'name {0}'.format(' '.join(self.donors))).ix - for i, atom_ix in enumerate(self._s2_donors): - tmp = self._get_bonded_hydrogens(self.u.atoms[atom_ix]).ix - for atom in tmp: + for atom_ix in self._s2_donors: + atom = self.u.atoms[atom_ix] + residue = atom.residue + hydrogens = residue.atoms.select_atoms('name {0}'.format( + ' '.join(self._residue_dict[residue.resname][atom.name]))).ix + for atom in hydrogens: self._s2_h_donors[atom] = atom_ix self._s2_donors_h[atom_ix].append(atom) self.logger_debug("Selection 2 donors: {0:d}".format(len(self._s2_donors))) @@ -914,9 +932,12 @@ def _update_water_selection(self): else: self._water_donors = self.u.atoms[self._water].select_atoms( 'name {0}'.format(' '.join(self.donors))).ix - for i, atom_ix in enumerate(self._water_donors): - tmp = self._get_bonded_hydrogens(self.u.atoms[atom_ix]).ix - for atom in tmp: + for atom_ix in self._water_donors: + atom = self.u.atoms[atom_ix] + residue = atom.residue + hydrogens = residue.atoms.select_atoms('name {0}'.format( + ' '.join(self._residue_dict[residue.resname][atom.name]))).ix + for atom in hydrogens: self._water_h_donors[atom] = atom_ix self._water_donors_h[atom_ix].append(atom) self.logger_debug("Water donors: {0}".format(len(self._water_donors))) @@ -969,11 +990,17 @@ def _prepare(self): self.selection_distance = (2 * 2 + self.order * (2 + self.distance)) self.box = self.u.dimensions if self.pbc else None + self._residue_dict = {} + self._build_residue_dict(self.selection1) + self._build_residue_dict(self.selection2) + self._build_residue_dict(self.water_selection) + self._update_selection() self.timesteps = [] if len(self._s1) and len(self._s2): self._update_water_selection() + else: logger.info("WaterBridgeAnalysis: no atoms found in the selection.") logger.info("WaterBridgeAnalysis: initial checks passed.") From 3cc262086c74c287daa7eff0cc5488b23d16aea1 Mon Sep 17 00:00:00 2001 From: zhiyiwu Date: Sun, 9 Feb 2020 20:50:12 +0000 Subject: [PATCH 2/3] bug fix --- .../analysis/hbonds/wbridge_analysis.py | 35 ++++++++----------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/package/MDAnalysis/analysis/hbonds/wbridge_analysis.py b/package/MDAnalysis/analysis/hbonds/wbridge_analysis.py index 5413f7522fb..8206cc43a62 100644 --- a/package/MDAnalysis/analysis/hbonds/wbridge_analysis.py +++ b/package/MDAnalysis/analysis/hbonds/wbridge_analysis.py @@ -832,6 +832,17 @@ def _build_residue_dict(self, selection): if atom.name in self.donors: self._residue_dict[residue.resname][atom.name].update(self._get_bonded_hydrogens(atom).names) + def _update_donor_h(self, atom_ix, h_donors, donors_h): + atom = self.u.atoms[atom_ix] + residue = atom.residue + hydrogen_names = self._residue_dict[residue.resname][atom.name] + if hydrogen_names: + hydrogens = residue.atoms.select_atoms('name {0}'.format( + ' '.join(self._residue_dict[residue.resname][atom.name]))).ix + for atom in hydrogens: + h_donors[atom] = atom_ix + donors_h[atom_ix].append(atom) + def _update_selection(self): self._s1_donors = [] self._s1_h_donors = {} @@ -874,13 +885,7 @@ def _update_selection(self): self._s1_donors = self.u.atoms[self._s1].select_atoms( 'name {0}'.format(' '.join(self.donors))).ix for atom_ix in self._s1_donors: - atom = self.u.atoms[atom_ix] - residue = atom.residue - hydrogens = residue.atoms.select_atoms('name {0}'.format( - ' '.join(self._residue_dict[residue.resname][atom.name]))).ix - for atom in hydrogens: - self._s1_h_donors[atom] = atom_ix - self._s1_donors_h[atom_ix].append(atom) + self._update_donor_h(atom_ix, self._s1_h_donors, self._s1_donors_h) self.logger_debug("Selection 1 donors: {0}".format(len(self._s1_donors))) self.logger_debug("Selection 1 donor hydrogens: {0}".format(len(self._s1_h_donors))) if self.selection1_type in ('acceptor', 'both'): @@ -898,13 +903,7 @@ def _update_selection(self): self._s2_donors = self.u.atoms[self._s2].select_atoms( 'name {0}'.format(' '.join(self.donors))).ix for atom_ix in self._s2_donors: - atom = self.u.atoms[atom_ix] - residue = atom.residue - hydrogens = residue.atoms.select_atoms('name {0}'.format( - ' '.join(self._residue_dict[residue.resname][atom.name]))).ix - for atom in hydrogens: - self._s2_h_donors[atom] = atom_ix - self._s2_donors_h[atom_ix].append(atom) + self._update_donor_h(atom_ix, self._s2_h_donors, self._s2_donors_h) self.logger_debug("Selection 2 donors: {0:d}".format(len(self._s2_donors))) self.logger_debug("Selection 2 donor hydrogens: {0:d}".format(len(self._s2_h_donors))) @@ -933,13 +932,7 @@ def _update_water_selection(self): self._water_donors = self.u.atoms[self._water].select_atoms( 'name {0}'.format(' '.join(self.donors))).ix for atom_ix in self._water_donors: - atom = self.u.atoms[atom_ix] - residue = atom.residue - hydrogens = residue.atoms.select_atoms('name {0}'.format( - ' '.join(self._residue_dict[residue.resname][atom.name]))).ix - for atom in hydrogens: - self._water_h_donors[atom] = atom_ix - self._water_donors_h[atom_ix].append(atom) + self._update_donor_h(atom_ix, self._water_h_donors, self._water_donors_h) self.logger_debug("Water donors: {0}".format(len(self._water_donors))) self.logger_debug("Water donor hydrogens: {0}".format(len(self._water_h_donors))) self._water_acceptors = self.u.atoms[self._water].select_atoms( From 27912898ca98ee7fbf8100078279780b84bf46c4 Mon Sep 17 00:00:00 2001 From: zhiyiwu Date: Mon, 10 Feb 2020 10:07:22 +0000 Subject: [PATCH 3/3] small fix --- package/MDAnalysis/analysis/hbonds/wbridge_analysis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/MDAnalysis/analysis/hbonds/wbridge_analysis.py b/package/MDAnalysis/analysis/hbonds/wbridge_analysis.py index 8206cc43a62..3e7453f0edf 100644 --- a/package/MDAnalysis/analysis/hbonds/wbridge_analysis.py +++ b/package/MDAnalysis/analysis/hbonds/wbridge_analysis.py @@ -838,7 +838,7 @@ def _update_donor_h(self, atom_ix, h_donors, donors_h): hydrogen_names = self._residue_dict[residue.resname][atom.name] if hydrogen_names: hydrogens = residue.atoms.select_atoms('name {0}'.format( - ' '.join(self._residue_dict[residue.resname][atom.name]))).ix + ' '.join(hydrogen_names))).ix for atom in hydrogens: h_donors[atom] = atom_ix donors_h[atom_ix].append(atom)