Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
12 changes: 11 additions & 1 deletion src/biotite/structure/bonds.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1648,7 +1648,8 @@ def connect_via_distances(atoms, dict distance_range=None, bint inter_residue=Tr


def connect_via_residue_names(atoms, bint inter_residue=True,
dict custom_bond_dict=None):
dict custom_bond_dict=None,
bint ignore_hetero=False):
"""
connect_via_residue_names(atoms, inter_residue=True, custom_bond_dict=None)

Expand All @@ -1674,6 +1675,8 @@ def connect_via_residue_names(atoms, bint inter_residue=True,
respective :class:`BondType` (represented as integer).
If given, these bonds are used instead of the bonds read from
``components.cif``.
ignore_hetero : bool, optional
If true, no bonds are created for hetero atoms.

Returns
-------
Expand Down Expand Up @@ -1735,6 +1738,7 @@ def connect_via_residue_names(atoms, bint inter_residue=True,
cdef np.ndarray atom_names = atoms.atom_name
cdef np.ndarray atom_names_in_res
cdef np.ndarray res_names = atoms.res_name
cdef np.ndarray hetero = atoms.hetero
cdef str atom_name1, atom_name2
cdef int64[:] atom_indices1, atom_indices2
cdef dict bond_dict_for_res
Expand All @@ -1745,6 +1749,12 @@ def connect_via_residue_names(atoms, bint inter_residue=True,
curr_start_i = residue_starts[res_i]
next_start_i = residue_starts[res_i+1]

# Skip lookup for ligands
# need to special case water, see test case 1crr where water CONECT entries are missing
# but present in cif.
if ignore_hetero and hetero[curr_start_i] and res_names[curr_start_i] != "HOH":
continue

if custom_bond_dict is None:
bond_dict_for_res = bonds_in_residue(res_names[curr_start_i])
else:
Expand Down
4 changes: 3 additions & 1 deletion src/biotite/structure/io/pdb/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,9 @@ def get_structure(
# Read bonds
if include_bonds:
bond_list = self._get_bonds(atom_id)
bond_list = bond_list.merge(connect_via_residue_names(array))
bond_list = bond_list.merge(
connect_via_residue_names(array, ignore_hetero=True)
)
array.bonds = bond_list

return array
Expand Down
10 changes: 10 additions & 0 deletions tests/structure/data/hetatm/ligand.pdb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
HETATM 704 C7 LIG B 101 -17.432 24.497 -0.918 1.00 26.28 C
HETATM 705 C8 LIG B 101 -17.432 24.497 -0.918 1.00 26.28 C
HETATM 706 C13 LIG B 101 -17.432 24.497 -0.918 1.00 26.28 C
HETATM 707 C14 LIG B 101 -17.432 24.497 -0.918 1.00 26.28 C
HETATM 708 C15 LIG B 101 -17.432 24.497 -0.918 1.00 26.28 C
CONECT 704 705
CONECT 705 704 706
CONECT 706 705 707
CONECT 707 706 708
CONECT 708 707
24 changes: 23 additions & 1 deletion tests/structure/io/test_pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,6 @@ def test_bond_parsing():

ref_bonds = struc.connect_via_residue_names(atoms)
ref_bonds.remove_bond_order()

assert test_bonds.as_set() == ref_bonds.as_set()


Expand Down Expand Up @@ -572,3 +571,26 @@ def test_setting_incompatible_structure(annotation, value, warning_only):
else:
with pytest.raises(struc.BadStructureError):
pdb_file.set_structure(atoms)


def test_hetatm_intra_residue_bonds():
"""
Expect that HETATM intra-residues bonds are only parsed from CONECT records
and not looked up via residue names.
"""
expected_bonds = np.array(
[
[0, 1, 0],
[1, 2, 0],
[2, 3, 0],
[3, 4, 0],
],
dtype=np.uint32,
)
path = join(data_dir("structure"), "hetatm/ligand.pdb")

pdb_file = pdb.PDBFile.read(path)
structure = pdb.get_structure(pdb_file, model=1, include_bonds=True)
actual_bonds = structure.bonds.as_array()

np.testing.assert_array_equal(actual_bonds, expected_bonds)