Editing structures#
The most basic way to manipulate a structure is to edit the annotation arrays or coordinates directly.
from tempfile import gettempdir
import biotite.database.rcsb as rcsb
import biotite.structure as struc
import biotite.structure.io.pdbx as pdbx
pdbx_file = pdbx.BinaryCIFFile.read(rcsb.fetch("1l2y", "bcif", gettempdir()))
structure = pdbx.get_structure(pdbx_file, model=1)
print("Before:")
print(structure[structure.res_id == 1])
print()
structure.coord += 100
print("After:")
print(structure[structure.res_id == 1])
Before:
A 1 ASN N N -8.901 4.127 -0.555
A 1 ASN CA C -8.608 3.135 -1.618
A 1 ASN C C -7.117 2.964 -1.897
A 1 ASN O O -6.634 1.849 -1.758
A 1 ASN CB C -9.437 3.396 -2.889
A 1 ASN CG C -10.915 3.130 -2.611
A 1 ASN OD1 O -11.269 2.700 -1.524
A 1 ASN ND2 N -11.806 3.406 -3.543
A 1 ASN H1 H -8.330 3.957 0.261
A 1 ASN H2 H -8.740 5.068 -0.889
A 1 ASN H3 H -9.877 4.041 -0.293
A 1 ASN HA H -8.930 2.162 -1.239
A 1 ASN HB2 H -9.310 4.417 -3.193
A 1 ASN HB3 H -9.108 2.719 -3.679
A 1 ASN HD21 H -11.572 3.791 -4.444
A 1 ASN HD22 H -12.757 3.183 -3.294
After:
A 1 ASN N N 91.099 104.127 99.445
A 1 ASN CA C 91.392 103.135 98.382
A 1 ASN C C 92.883 102.964 98.103
A 1 ASN O O 93.366 101.849 98.242
A 1 ASN CB C 90.563 103.396 97.111
A 1 ASN CG C 89.085 103.130 97.389
A 1 ASN OD1 O 88.731 102.700 98.476
A 1 ASN ND2 N 88.194 103.406 96.457
A 1 ASN H1 H 91.670 103.957 100.261
A 1 ASN H2 H 91.260 105.068 99.111
A 1 ASN H3 H 90.123 104.041 99.707
A 1 ASN HA H 91.070 102.162 98.761
A 1 ASN HB2 H 90.690 104.417 96.807
A 1 ASN HB3 H 90.892 102.719 96.321
A 1 ASN HD21 H 88.428 103.791 95.556
A 1 ASN HD22 H 87.243 103.183 96.706
Biotite provides also some transformation functions, for example
rotate() for rotations about the x-, y- or z-axis.
structure = pdbx.get_structure(pdbx_file, model=1)
print("Before:")
print(structure[structure.res_id == 1])
print()
# Rotation about z-axis by 90 degrees
structure = struc.rotate(structure, [0, 0, np.deg2rad(90)])
print("After:")
print(structure[structure.res_id == 1])
Before:
A 1 ASN N N -8.901 4.127 -0.555
A 1 ASN CA C -8.608 3.135 -1.618
A 1 ASN C C -7.117 2.964 -1.897
A 1 ASN O O -6.634 1.849 -1.758
A 1 ASN CB C -9.437 3.396 -2.889
A 1 ASN CG C -10.915 3.130 -2.611
A 1 ASN OD1 O -11.269 2.700 -1.524
A 1 ASN ND2 N -11.806 3.406 -3.543
A 1 ASN H1 H -8.330 3.957 0.261
A 1 ASN H2 H -8.740 5.068 -0.889
A 1 ASN H3 H -9.877 4.041 -0.293
A 1 ASN HA H -8.930 2.162 -1.239
A 1 ASN HB2 H -9.310 4.417 -3.193
A 1 ASN HB3 H -9.108 2.719 -3.679
A 1 ASN HD21 H -11.572 3.791 -4.444
A 1 ASN HD22 H -12.757 3.183 -3.294
After:
A 1 ASN N N -4.127 -8.901 -0.555
A 1 ASN CA C -3.135 -8.608 -1.618
A 1 ASN C C -2.964 -7.117 -1.897
A 1 ASN O O -1.849 -6.634 -1.758
A 1 ASN CB C -3.396 -9.437 -2.889
A 1 ASN CG C -3.130 -10.915 -2.611
A 1 ASN OD1 O -2.700 -11.269 -1.524
A 1 ASN ND2 N -3.406 -11.806 -3.543
A 1 ASN H1 H -3.957 -8.330 0.261
A 1 ASN H2 H -5.068 -8.740 -0.889
A 1 ASN H3 H -4.041 -9.877 -0.293
A 1 ASN HA H -2.162 -8.930 -1.239
A 1 ASN HB2 H -4.417 -9.310 -3.193
A 1 ASN HB3 H -2.719 -9.108 -3.679
A 1 ASN HD21 H -3.791 -11.572 -4.444
A 1 ASN HD22 H -3.183 -12.757 -3.294
Structure superimposition#
A common prerequisite to compare two structures is the superimposing them onto each other. This means translating and rotating one structure so that the root mean square deviation (RMSD) between corresponding atoms in the two structures is minimized. To demonstrate this, we will use two models of the TC5b structure already used in the previous chapters.
reference = pdbx.get_structure(pdbx_file, model=1)
# Rotate reference to remove the superimposition originating from the file
reference = struc.rotate(reference, [np.deg2rad(45), 0, 0])
mobile = pdbx.get_structure(pdbx_file, model=2)
print(f"RMSD before superimposition: {struc.rmsd(reference, mobile):.2f}")
superimposed, transformation = struc.superimpose(reference, mobile)
print(f"RMSD after superimposition: {struc.rmsd(reference, superimposed):.2f}")
RMSD before superimposition: 4.61
RMSD after superimposition: 1.93
Note
It is required that both structures have the same number (and order) of atoms, as the algorithm requires that each atom corresponds to an atom in the other structure.
The returned AffineTransformation object can be used later to
transform another structure in the same way the mobile structure was
transformed.
another_model = pdbx.get_structure(pdbx_file, model=3)
print(f"RMSD before transformation: {struc.rmsd(mobile, another_model):.2f}")
# Apply the same transformation that was applied on the mobile structure
transformed = transformation.apply(another_model)
print(f"RMSD after transformation: {struc.rmsd(superimposed, transformed):.2f}")
RMSD before transformation: 1.57
RMSD after transformation: 1.57
We can see that both RMSD values are equal:
As the same transformation was applied to mobile and another_model,
the atom positions relative to each other did not change.