Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve MolecularContainer.top_up_conformations #167

Merged
merged 1 commit into from
Sep 17, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
16 changes: 15 additions & 1 deletion propka/conformation_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from propka.determinants import set_backbone_determinants, set_ion_determinants
from propka.determinants import set_determinants
from propka.group import Group, is_group
from typing import Iterable


_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -553,9 +554,22 @@ def top_up(self, other):
Args:
other: conformation container with atoms to add
"""
self.top_up_from_atoms(other.atoms)

def top_up_from_atoms(self, other_atoms: Iterable["propka.atom.Atom"]):
"""Adds atoms which are missing from this container.

Args:
other_atoms: Reference atoms
"""
my_residue_labels = {a.residue_label for a in self.atoms}
for atom in other.atoms:
res_names = {(a.chain_id, a.res_num): a.res_name for a in self.atoms}
for atom in other_atoms:
if atom.residue_label not in my_residue_labels:
if res_names.setdefault((atom.chain_id, atom.res_num),
atom.res_name) != atom.res_name:
# don't merge different residue types, e.g. alt-loc mutant
continue
self.copy_atom(atom)

def find_group(self, group):
Expand Down
11 changes: 7 additions & 4 deletions propka/molecular_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,13 @@ def __init__(self, parameters, options=None):

def top_up_conformations(self):
"""Makes sure that all atoms are present in all conformations."""
first = self.conformations[self.conformation_names[0]]
for name in self.conformation_names[1:]:
if len(self.conformations[name]) < len(first):
self.conformations[name].top_up(first)
ref_atoms = {
atom.residue_label: atom
for name in reversed(self.conformation_names)
for atom in self.conformations[name].atoms
}
for conf in self.conformations.values():
conf.top_up_from_atoms(ref_atoms.values())

def find_covalently_coupled_groups(self):
"""Find covalently coupled groups."""
Expand Down
23 changes: 23 additions & 0 deletions tests/pdb/conf-alt-AB-mutant.pdb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
ATOM 1 N GLY 1 2.037 -0.982 0.836 1.00 0.00 N
ATOM 2 CA GLY 1 3.462 -0.865 0.540 1.00 0.00 C
ATOM 3 C GLY 1 4.291 -1.573 1.584 1.00 0.00 C
ATOM 4 O GLY 1 3.777 -2.158 2.541 1.00 0.00 O
ATOM 5 N ASER 2 5.576 -1.566 1.473 1.00 0.00 N
ATOM 6 CA ASER 2 6.377 -2.251 2.483 1.00 0.00 C
ATOM 7 C ASER 2 7.852 -2.130 2.177 1.00 0.00 C
ATOM 8 O ASER 2 8.265 -1.521 1.190 1.00 0.00 O
ATOM 9 CB ASER 2 5.943 -3.732 2.620 1.00 0.00 C
ATOM 10 OG ASER 2 6.285 -4.520 1.474 1.00 0.00 O
ATOM 11 N BVAL 2 5.577 -1.568 1.470 1.00 0.00 N
ATOM 12 CA BVAL 2 6.380 -2.234 2.491 1.00 0.00 C
ATOM 13 C BVAL 2 7.853 -2.130 2.173 1.00 0.00 C
ATOM 14 O BVAL 2 8.265 -1.521 1.190 1.00 0.00 O
ATOM 15 CB BVAL 2 5.939 -3.746 2.618 1.00 0.00 C
ATOM 16 CG1BVAL 2 5.960 -4.584 1.310 1.00 0.00 C
ATOM 17 CG2BVAL 2 6.774 -4.559 3.636 1.00 0.00 C
ATOM 18 N GLY 3 8.703 -2.681 2.974 1.00 0.00 N
ATOM 19 CA GLY 3 10.128 -2.564 2.677 1.00 0.00 C
ATOM 20 C GLY 3 10.957 -3.272 3.721 1.00 0.00 C
ATOM 21 O GLY 3 10.444 -3.857 4.678 1.00 0.00 O
TER
END
19 changes: 19 additions & 0 deletions tests/pdb/conf-alt-AB.pdb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
ATOM 1 N GLY 1 2.037 -0.982 0.836 1.00 0.00 N
ATOM 2 CA GLY 1 3.462 -0.865 0.540 1.00 0.00 C
ATOM 3 C GLY 1 4.291 -1.573 1.584 1.00 0.00 C
ATOM 4 O GLY 1 3.777 -2.158 2.541 1.00 0.00 O
ATOM 5 N SER 2 5.576 -1.566 1.473 1.00 0.00 N
ATOM 6 CA ASER 2 6.377 -2.251 2.483 1.00 0.00 C
ATOM 7 CA BSER 2 6.377 -2.251 2.483 1.00 0.00 C
ATOM 8 C SER 2 7.852 -2.130 2.177 1.00 0.00 C
ATOM 9 O SER 2 8.265 -1.521 1.190 1.00 0.00 O
ATOM 10 CB ASER 2 5.943 -3.732 2.620 1.00 0.00 C
ATOM 11 CB BSER 2 5.943 -3.732 2.620 1.00 0.00 C
ATOM 12 OG ASER 2 6.285 -4.520 1.474 1.00 0.00 O
ATOM 13 OG BSER 2 6.994 -4.577 3.101 1.00 0.00 O
ATOM 14 N GLY 3 8.703 -2.681 2.974 1.00 0.00 N
ATOM 15 CA GLY 3 10.128 -2.564 2.677 1.00 0.00 C
ATOM 16 C GLY 3 10.957 -3.272 3.721 1.00 0.00 C
ATOM 17 O GLY 3 10.444 -3.857 4.678 1.00 0.00 O
TER
END
19 changes: 19 additions & 0 deletions tests/pdb/conf-alt-BC.pdb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
ATOM 1 N GLY 1 2.037 -0.982 0.836 1.00 0.00 N
ATOM 2 CA GLY 1 3.462 -0.865 0.540 1.00 0.00 C
ATOM 3 C GLY 1 4.291 -1.573 1.584 1.00 0.00 C
ATOM 4 O GLY 1 3.777 -2.158 2.541 1.00 0.00 O
ATOM 5 N SER 2 5.576 -1.566 1.473 1.00 0.00 N
ATOM 6 CA BSER 2 6.377 -2.251 2.483 1.00 0.00 C
ATOM 7 CA CSER 2 6.377 -2.251 2.483 1.00 0.00 C
ATOM 8 C SER 2 7.852 -2.130 2.177 1.00 0.00 C
ATOM 9 O SER 2 8.265 -1.521 1.190 1.00 0.00 O
ATOM 10 CB BSER 2 5.943 -3.732 2.620 1.00 0.00 C
ATOM 11 CB CSER 2 5.943 -3.732 2.620 1.00 0.00 C
ATOM 12 OG BSER 2 6.285 -4.520 1.474 1.00 0.00 O
ATOM 13 OG CSER 2 6.994 -4.577 3.101 1.00 0.00 O
ATOM 14 N GLY 3 8.703 -2.681 2.974 1.00 0.00 N
ATOM 15 CA GLY 3 10.128 -2.564 2.677 1.00 0.00 C
ATOM 16 C GLY 3 10.957 -3.272 3.721 1.00 0.00 C
ATOM 17 O GLY 3 10.444 -3.857 4.678 1.00 0.00 O
TER
END
45 changes: 45 additions & 0 deletions tests/pdb/conf-model-missing-atoms.pdb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
MODEL 1
ATOM 1 N GLY 1 2.037 -0.982 0.836 1.00 0.00 N
ATOM 2 CA GLY 1 3.462 -0.865 0.540 1.00 0.00 C
ATOM 3 C GLY 1 4.291 -1.573 1.584 1.00 0.00 C
ATOM 4 O GLY 1 3.777 -2.158 2.541 1.00 0.00 O
ATOM 5 N VAL 2 5.577 -1.568 1.470 1.00 0.00 N
ATOM 6 CA VAL 2 6.380 -2.234 2.491 1.00 0.00 C
ATOM 7 C VAL 2 7.853 -2.130 2.173 1.00 0.00 C
ATOM 8 O VAL 2 8.265 -1.521 1.190 1.00 0.00 O
ATOM 9 CB VAL 2 5.939 -3.746 2.618 1.00 0.00 C
ATOM 10 N GLY 3 8.703 -2.681 2.974 1.00 0.00 N
ATOM 11 CA GLY 3 10.128 -2.564 2.677 1.00 0.00 C
ATOM 12 C GLY 3 10.957 -3.272 3.721 1.00 0.00 C
ATOM 13 O GLY 3 10.444 -3.857 4.678 1.00 0.00 O
TER
ENDMDL
MODEL 2
ATOM 14 N GLY 1 2.037 -0.982 0.836 1.00 0.00 N
ATOM 15 CA GLY 1 3.462 -0.865 0.540 1.00 0.00 C
ATOM 16 C GLY 1 4.291 -1.573 1.584 1.00 0.00 C
ATOM 17 O GLY 1 3.777 -2.158 2.541 1.00 0.00 O
ATOM 18 N VAL 2 5.577 -1.568 1.470 1.00 0.00 N
ATOM 19 CA VAL 2 6.380 -2.234 2.491 1.00 0.00 C
ATOM 20 C VAL 2 7.853 -2.130 2.173 1.00 0.00 C
ATOM 21 O VAL 2 8.265 -1.521 1.190 1.00 0.00 O
ATOM 22 CB VAL 2 5.939 -3.746 2.618 1.00 0.00 C
ATOM 23 CG1 VAL 2 5.960 -4.584 1.310 1.00 0.00 C
ATOM 24 CG2 VAL 2 6.774 -4.559 3.636 1.00 0.00 C
ATOM 25 N GLY 3 8.703 -2.681 2.974 1.00 0.00 N
ATOM 26 CA GLY 3 10.128 -2.564 2.677 1.00 0.00 C
ATOM 27 C GLY 3 10.957 -3.272 3.721 1.00 0.00 C
ATOM 28 O GLY 3 10.444 -3.857 4.678 1.00 0.00 O
TER
ENDMDL
MODEL 3
ATOM 29 CA GLY 1 3.462 -0.865 0.540 1.00 0.00 C
ATOM 30 C GLY 1 4.291 -1.573 1.584 1.00 0.00 C
ATOM 31 O GLY 1 3.777 -2.158 2.541 1.00 0.00 O
ATOM 32 N VAL 2 5.577 -1.568 1.470 1.00 0.00 N
ATOM 33 CA VAL 2 6.380 -2.234 2.491 1.00 0.00 C
ATOM 34 C VAL 2 7.853 -2.130 2.173 1.00 0.00 C
ATOM 35 O VAL 2 8.265 -1.521 1.190 1.00 0.00 O
TER
ENDMDL
END
36 changes: 36 additions & 0 deletions tests/pdb/conf-model-mutant.pdb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
MODEL 1
ATOM 1 N GLY 1 2.037 -0.982 0.836 1.00 0.00 N
ATOM 2 CA GLY 1 3.462 -0.865 0.540 1.00 0.00 C
ATOM 3 C GLY 1 4.291 -1.573 1.584 1.00 0.00 C
ATOM 4 O GLY 1 3.777 -2.158 2.541 1.00 0.00 O
ATOM 5 N SER 2 5.576 -1.566 1.473 1.00 0.00 N
ATOM 6 CA SER 2 6.377 -2.251 2.483 1.00 0.00 C
ATOM 7 C SER 2 7.852 -2.130 2.177 1.00 0.00 C
ATOM 8 O SER 2 8.265 -1.521 1.190 1.00 0.00 O
ATOM 9 CB SER 2 5.943 -3.732 2.620 1.00 0.00 C
ATOM 10 OG SER 2 6.285 -4.520 1.474 1.00 0.00 O
ATOM 11 N GLY 3 8.703 -2.681 2.974 1.00 0.00 N
ATOM 12 CA GLY 3 10.128 -2.564 2.677 1.00 0.00 C
ATOM 13 C GLY 3 10.957 -3.272 3.721 1.00 0.00 C
ATOM 14 O GLY 3 10.444 -3.857 4.678 1.00 0.00 O
TER
ENDMDL
MODEL 2
ATOM 15 N GLY 1 2.037 -0.982 0.836 1.00 0.00 N
ATOM 16 CA GLY 1 3.462 -0.865 0.540 1.00 0.00 C
ATOM 17 C GLY 1 4.291 -1.573 1.584 1.00 0.00 C
ATOM 18 O GLY 1 3.777 -2.158 2.541 1.00 0.00 O
ATOM 19 N VAL 2 5.577 -1.568 1.470 1.00 0.00 N
ATOM 20 CA VAL 2 6.380 -2.234 2.491 1.00 0.00 C
ATOM 21 C VAL 2 7.853 -2.130 2.173 1.00 0.00 C
ATOM 22 O VAL 2 8.265 -1.521 1.190 1.00 0.00 O
ATOM 23 CB VAL 2 5.939 -3.746 2.618 1.00 0.00 C
ATOM 24 CG1 VAL 2 5.960 -4.584 1.310 1.00 0.00 C
ATOM 25 CG2 VAL 2 6.774 -4.559 3.636 1.00 0.00 C
ATOM 26 N GLY 3 8.703 -2.681 2.974 1.00 0.00 N
ATOM 27 CA GLY 3 10.128 -2.564 2.677 1.00 0.00 C
ATOM 28 C GLY 3 10.957 -3.272 3.721 1.00 0.00 C
ATOM 29 O GLY 3 10.444 -3.857 4.678 1.00 0.00 O
TER
ENDMDL
END
56 changes: 56 additions & 0 deletions tests/test_molecular_container.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from propka.input import read_parameter_file, read_molecule_file
from propka.lib import loadOptions
from propka.molecular_container import MolecularContainer
from propka.parameters import Parameters
from pathlib import Path
from pytest import approx

TESTS = Path(__file__).resolve().parent


def load_molecule(code):
pdb_path = TESTS / f"pdb/{code}.pdb"
options = [str(pdb_path)]
args = loadOptions(options)
parameters = read_parameter_file(args.parameters, Parameters())
molecule = MolecularContainer(parameters, args)
molecule = read_molecule_file(str(pdb_path), molecule)
return molecule


def test_MolecularContainer_get_pi():
molecule = load_molecule("1HPX")
molecule.average_of_conformations()
molecule.calculate_pka()
pi_folded, pi_unfolded = molecule.get_pi()
assert pi_folded == approx(9.54, abs=1e-2)
assert pi_unfolded == approx(8.90, abs=1e-2)


def test_MolecularContainer_top_up_conformations():
molecule = load_molecule("conf-alt-AB")
assert len(molecule.conformations) == 2
assert len(molecule.conformations["1A"]) == 16
assert len(molecule.conformations["1B"]) == 16

molecule = load_molecule("conf-alt-BC")
assert len(molecule.conformations) == 3
assert len(molecule.conformations["1A"]) == 16
assert len(molecule.conformations["1B"]) == 16
assert len(molecule.conformations["1C"]) == 16

molecule = load_molecule("conf-alt-AB-mutant")
assert len(molecule.conformations) == 2
assert len(molecule.conformations["1A"]) == 16
assert len(molecule.conformations["1B"]) == 17

molecule = load_molecule("conf-model-mutant")
assert len(molecule.conformations) == 2
assert len(molecule.conformations["1A"]) == 16
assert len(molecule.conformations["2A"]) == 17

molecule = load_molecule("conf-model-missing-atoms")
assert len(molecule.conformations) == 3
assert len(molecule.conformations["1A"]) == 17
assert len(molecule.conformations["2A"]) == 17
assert len(molecule.conformations["3A"]) == 17
Loading