diff --git a/src/biotite/structure/bonds.pyx b/src/biotite/structure/bonds.pyx index 35331c09d..ac62428dc 100644 --- a/src/biotite/structure/bonds.pyx +++ b/src/biotite/structure/bonds.pyx @@ -74,8 +74,8 @@ class BondType(IntEnum): """ Remove aromaticity from the bond type. - :attr:`BondType.AROMATIC_` is converted into - :attr:`BondType.`. + :attr:`BondType.AROMATIC_{ORDER}` is converted into + :attr:`BondType.{ORDER}`. Returns ------- @@ -157,6 +157,8 @@ class BondList(Copyable): sanitized: Redundant bonds are removed, and each bond entry is sorted so that the lower one of the two atom indices is in the first column. + If a bond appears multiple times with different bond types, the + first bond takes precedence. Examples -------- @@ -436,8 +438,8 @@ class BondList(Copyable): """ Remove aromaticity from the bond types. - :attr:`BondType.AROMATIC_` is converted into - :attr:`BondType.`. + :attr:`BondType.AROMATIC_{ORDER}` is converted into + :attr:`BondType.{ORDER}`. Examples -------- @@ -929,12 +931,14 @@ class BondList(Copyable): """ merge(bond_list) - Merge this instance with another :class:`BondList` into a new + Merge another :class:`BondList` with this instance into a new object. + If a bond appears in both :class:`BondList`'s, the + :class:`BondType` from the given `bond_list` takes precedence. The internal :class:`ndarray` instances containg the bonds are - simply concatenated and the new atom count is the maximum atom - count of the merged bond lists. + simply concatenated and the new atom count is the maximum of + both bond lists. Parameters ---------- @@ -956,7 +960,7 @@ class BondList(Copyable): >>> bond_list1 = BondList(3, np.array([(0,1),(1,2)])) >>> bond_list2 = BondList(5, np.array([(2,3),(3,4)])) - >>> merged_list = bond_list1.merge(bond_list2) + >>> merged_list = bond_list2.merge(bond_list1) >>> print(merged_list.get_atom_count()) 5 >>> print(merged_list) @@ -964,12 +968,30 @@ class BondList(Copyable): [1 2 0] [2 3 0] [3 4 0]] + + The BondList given as parameter takes precedence: + + # Specifiy bond type to see where a bond is taken from + >>> bond_list1 = BondList(4, np.array([ + ... (0, 1, BondType.SINGLE), + ... (1, 2, BondType.SINGLE) + ... ])) + >>> bond_list2 = BondList(4, np.array([ + ... (1, 2, BondType.DOUBLE), # This one is a duplicate + ... (2, 3, BondType.DOUBLE) + ... ])) + >>> merged_list = bond_list2.merge(bond_list1) + >>> print(merged_list) + [[0 1 1] + [1 2 1] + [2 3 2]] """ return BondList( max(self._atom_count, bond_list._atom_count), - np.concatenate([self.as_array(), - bond_list.as_array()], - axis=0) + np.concatenate( + [bond_list.as_array(), self.as_array()], + axis=0 + ) ) def __add__(self, bond_list): @@ -1688,7 +1710,7 @@ def _connect_inter_residue(atoms, residue_starts): # Get link type for this residue from RCSB components.cif curr_link = link_type(res_names[curr_start_i]) - next_link = link_type(res_names[curr_start_i+1]) + next_link = link_type(res_names[next_start_i]) if curr_link in _PEPTIDE_LINKS and next_link in _PEPTIDE_LINKS: curr_connect_atom_name = "C" diff --git a/src/biotite/structure/io/pdb/convert.py b/src/biotite/structure/io/pdb/convert.py index 415ebacca..7d4bc19dd 100644 --- a/src/biotite/structure/io/pdb/convert.py +++ b/src/biotite/structure/io/pdb/convert.py @@ -72,8 +72,11 @@ def get_structure(pdb_file, model=None, altloc="first", extra_fields=[], If set to true, a :class:`BondList` will be created for the resulting :class:`AtomArray` containing the bond information from the file. - All bonds have :attr:`BondType.ANY`, since the PDB format - does not support bond orders. + Bonds, whose order could not be determined from the + *Chemical Component Dictionary* + (e.g. especially inter-residue bonds), + have :attr:`BondType.ANY`, since the PDB format itself does + not support bond orders. Returns ------- @@ -191,8 +194,11 @@ def get_assembly(pdb_file, assembly_id=None, model=None, altloc="first", If set to true, a :class:`BondList` will be created for the resulting :class:`AtomArray` containing the bond information from the file. - All bonds have :attr:`BondType.ANY`, since the PDB format - does not support bond orders. + Bonds, whose order could not be determined from the + *Chemical Component Dictionary* + (e.g. especially inter-residue bonds), + have :attr:`BondType.ANY`, since the PDB format itself does + not support bond orders. Returns ------- @@ -257,8 +263,11 @@ def get_symmetry_mates(pdb_file, model=None, altloc="first", If set to true, a :class:`BondList` will be created for the resulting :class:`AtomArray` containing the bond information from the file. - All bonds have :attr:`BondType.ANY`, since the PDB format - does not support bond orders. + Bonds, whose order could not be determined from the + *Chemical Component Dictionary* + (e.g. especially inter-residue bonds), + have :attr:`BondType.ANY`, since the PDB format itself does + not support bond orders. Returns ------- diff --git a/src/biotite/structure/io/pdb/file.py b/src/biotite/structure/io/pdb/file.py index bd017377b..e131bdb33 100644 --- a/src/biotite/structure/io/pdb/file.py +++ b/src/biotite/structure/io/pdb/file.py @@ -360,8 +360,11 @@ def get_structure(self, model=None, altloc="first", extra_fields=[], If set to true, a :class:`BondList` will be created for the resulting :class:`AtomArray` containing the bond information from the file. - All bonds have :attr:`BondType.ANY`, since the PDB format - does not support bond orders. + Bonds, whose order could not be determined from the + *Chemical Component Dictionary* + (e.g. especially inter-residue bonds), + have :attr:`BondType.ANY`, since the PDB format itself does + not support bond orders. Returns ------- @@ -536,15 +539,8 @@ def get_structure(self, model=None, altloc="first", extra_fields=[], # Read bonds if include_bonds: bond_list = self._get_bonds(atom_id) - bond_list = bond_list.merge(connect_via_residue_names( - array, - # The information for non-hetero residues and water - # are not part of CONECT records - (~array.hetero) | filter_solvent(array) - )) - # Remove bond order from inter residue bonds for consistency - bond_list.remove_bond_order() - array.bonds = bond_list + bond_list = bond_list.merge(connect_via_residue_names(array)) + array.bonds = bond_list return array @@ -794,8 +790,11 @@ def get_assembly(self, assembly_id=None, model=None, altloc="first", If set to true, a :class:`BondList` will be created for the resulting :class:`AtomArray` containing the bond information from the file. - All bonds have :attr:`BondType.ANY`, since the PDB format - does not support bond orders. + Bonds, whose order could not be determined from the + *Chemical Component Dictionary* + (e.g. especially inter-residue bonds), + have :attr:`BondType.ANY`, since the PDB format itself does + not support bond orders. Returns ------- @@ -946,8 +945,11 @@ def get_symmetry_mates(self, model=None, altloc="first", If set to true, a :class:`BondList` will be created for the resulting :class:`AtomArray` containing the bond information from the file. - All bonds have :attr:`BondType.ANY`, since the PDB format - does not support bond orders. + Bonds, whose order could not be determined from the + *Chemical Component Dictionary* + (e.g. especially inter-residue bonds), + have :attr:`BondType.ANY`, since the PDB format itself does + not support bond orders. Returns ------- diff --git a/tests/structure/test_bonds.py b/tests/structure/test_bonds.py index d37b2d5b0..c558d2033 100644 --- a/tests/structure/test_bonds.py +++ b/tests/structure/test_bonds.py @@ -172,7 +172,7 @@ def test_merge(bond_list): """ Test merging two `BondList` objects on a known example. """ - merged_list = bond_list.merge(struc.BondList(8, np.array([(4,6),(6,7)]))) + merged_list = struc.BondList(8, np.array([(4,6),(6,7)])).merge(bond_list) assert merged_list.as_array().tolist() == [[0, 1, 0], [1, 2, 0], [1, 3, 0], diff --git a/tests/structure/test_pdb.py b/tests/structure/test_pdb.py index e47371045..c09088ddf 100644 --- a/tests/structure/test_pdb.py +++ b/tests/structure/test_pdb.py @@ -419,6 +419,7 @@ def test_bond_parsing(): atoms = pdb.get_structure(pdb_file, model=1, include_bonds=True) test_bonds = atoms.bonds + test_bonds.remove_bond_order() ref_bonds = struc.connect_via_residue_names(atoms) ref_bonds.remove_bond_order()