Coordinate manipulation

Atom positions

The position, positions and set_positions! functions are used to retrieve of set the coordinates of an atom (following the AtomBase.jl convention):

Base.position — Function
position(atom::Atom)

Returns the position of an atom given the Atom structure.

source
PDBToolsBase.set_position! — Function
set_position!(atom::Atom, x::Union{Tuple,AbstractVector})

Sets the position (x,y,z coordinates) of the atom, given a vector or tuple of coordinates.

source

Positions of arrays of Atoms

Use the positions function:

PDBToolsBase.positions — Method
positions(atoms::AbstractVector{<:Atom}; selection)

Returns the coordinates of the atoms. The input may be one atom (type Atom), a vector of atoms, or a Residue. The coordinates are returned as a vector of static vectors (from StaticArrays), more specifically as a Vector{SVector{3,Float64}}.

Examples

julia> using PDBTools, StaticArrays 

julia> protein = wget("1LBD");

julia> positions(protein[1])
3-element SVector{3, Float64} with indices SOneTo(3):
 45.228
 84.358
 70.638

julia> positions(protein[1], as=SVector{3,Float32})
3-element SVector{3, Float32} with indices SOneTo(3):
 45.228
 84.358
 70.638

julia> positions(protein, "index <= 2")
2-element Vector{SVector{3, Float64}}:
 [45.228, 84.358, 70.638]
 [46.08, 83.165, 70.327]

julia> positions(protein, at -> at.resname == "ALA")
110-element Vector{SVector{3, Float64}}:
 [43.94, 81.982, 70.474]
 [43.02, 80.825, 70.455]
 [41.996, 80.878, 69.34]
 ⋮
 [-17.866, 84.088, 51.741]
 [-18.496, 83.942, 52.777]
 [-15.888, 82.583, 51.706]
  
julia> residues = collect(eachresidue(protein));

julia> positions(residues[1])
6-element Vector{SVector{3, Float64}}:
 [45.228, 84.358, 70.638]
 [46.08, 83.165, 70.327]
 [45.257, 81.872, 70.236]
 [45.823, 80.796, 69.974]
 [47.147, 82.98, 71.413]
 [46.541, 82.639, 72.662]
source
julia> using PDBTools, LazyArtifacts

julia> atoms = read_pdb(PDBTools.test_file("small.pdb"));

julia> positions(atoms[1:2])
2-element Vector{StaticArraysCore.SVector{3, Float32}}:
 [-9.229, -14.861, -5.481]
 [-10.048, -15.427, -5.569]

The positions function accepts selections:

C$\alpha$ coordinates:

julia> using PDBTools, LazyArtifacts

julia> atoms = read_pdb(PDBTools.test_file("small.pdb"));

julia> positions(atoms, "name CA")
3-element Vector{StaticArraysCore.SVector{3, Float64}}:
 [-8.483, -14.912, -6.726]
 [-5.113, -13.737, -5.466]
 [-3.903, -11.262, -8.062]

The coordinates are output as arrays of static arrays (more specifically, as a Vector{SVector{3,Float64}}, from StaticArrays).

Move atoms and center of mass

The center_of_mass function can be used to compute the center of mass of set of atoms, and the moveto! function can be used to move the center of mass of the atoms to the origin (by default) or to a specified position:

PDBToolsBase.center_of_mass — Function
center_of_mass(x::AbstractVector{<:AbstractVector}[, mass::AbstractVector=nothing])

Calculate the center of mass of a set of points.

Arguments

  • x::AbstractVector{<:AbstractVector}: A vector of coordinates.
  • mass::AbstractVector: A vector of masses. If not provided, all masses are assumed to be equal.

Example

julia> import PDBTools: center_of_mass

julia> x = [ [1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0] ];

julia> center_of_mass(x)
3-element Vector{Float64}:
 4.0
 5.0
 6.0

julia> center_of_mass(x, [1.0, 2.0, 3.0]) # providing masses
3-element Vector{Float64}:
 5.0
 6.0
 7.0
source
center_of_mass(atoms::AbstractVector{<:Atom})

Calculate the center of mass of the atoms.

Example

julia> using PDBTools

julia> atoms = read_pdb(PDBTools.test_file("small.pdb"));

julia> center_of_mass(atoms)
3-element StaticArraysCore.SVector{3, Float32} with indices SOneTo(3):
  -5.5844226
 -13.1104145
  -7.1399713
source
PDBToolsBase.moveto! — Function
moveto!(atoms::AbstractVector{<:Atom}; center::AbstractVector{<:Real}=SVector(0.0, 0.0, 0.0))

Move the center of mass of the atoms to the specified center position, which defaults to the origin.

Example

julia> using PDBTools

julia> atoms = read_pdb(PDBTools.test_file("small.pdb"));

julia> center_of_mass(atoms)
3-element StaticArraysCore.SVector{3, Float32} with indices SOneTo(3):
  -5.5844226
 -13.1104145
  -7.1399713

julia> moveto!(atoms; center = [1.0, 2.0, 3.0]);

julia> center_of_mass(atoms)
3-element StaticArraysCore.SVector{3, Float32} with indices SOneTo(3):
 1.0
 2.0000014
 3.0
source

Distance between sets of atoms

The distance between atoms, or sets of atoms, can be computed with the distance function. This function returns the minimum distance between the atoms of the sets involved. For example:

julia> using PDBTools, LazyArtifacts

julia> model = wget("1BSX");

julia> protein = select(model,"protein");

julia> ligand = select(model,"resname T3");

julia> distance(protein,ligand)
2.7775834820937417
PDBToolsBase.distance — Function
distance(x,y)

Computes the minimum distance between two sets of atoms, between an atom and a set of atoms, or simply the distance between two atoms, or from the coordinates or sets of coordinates.

The input may be an Atom vector of Atoms, or a 3D vector, or a vector of 3D vector of coordinates, for examples as output by the positions function.

Examples

julia> model = wget("1BSX");

julia> protein = select(model,"protein");

julia> ligand = select(model,"resname T3");

julia> distance(protein,ligand)
2.7775834820937417

julia> distance(protein[1],ligand[3])
36.453551075306784

julia> distance(positions(ligand),protein)
2.7775834820937417
source

A special related function to compute the distance between a pair of residues is:

PDBToolsBase.residue_residue_distance — Function
residue_residue_distance(
    r1::PDBTools.Residue, 
    r2::PDBTools.Residue; 
    positions::AbstractVector{AbstractVector{T}}=nothing; 
    unitcell=false
)

Calculate the minimum distance between two residues in a protein structure. If the positions argument is not provided, the function calculates the distance using the coordinates of the atoms in the residues. If positions is provided, the function uses the coordinates in the positions array.

Arguments

  • r1::PDBTools.Residue: Residue 1
  • r2::PDBTools.Residue: Residue 2
  • positions::AbstractVector{AbstractVector{T}}: Optional alternate positions of the atoms in the structure.
  • unitcell=false: Periodic boundary conditions. false: no periodicity; true: use the unit cell of the Structure the residues belong to; a matrix or vector: the unit cell to be used.
Note

The index of the atoms in the residues must match the index of the atoms in the positions array.

Example

julia> using PDBTools

julia> ats = read_pdb(PDBTools.test_file("dimer.pdb"));

julia> residues = collect(eachresidue(ats));

julia> r1 = residues[1]; r10 = residues[10];

julia> println(name(r1), resnum(r1), " and ", name(r10), resnum(r10))
LYS211 and GLU220

julia> d = residue_residue_distance(r1, r10)
16.16511f0
source

Closest atoms and their distance

A function similar to the one above is closest, which returns the shortest distance between atoms but also the identity of the atom or pair of atoms that satisfy that shortest distance:

julia> using PDBTools, LazyArtifacts

julia> model = wget("1BSX");

julia> protein = select(model,"protein");

julia> ligand = select(model,"resname T3");

julia> closest(ligand,protein)
(43, 3684, 2.7775834820937417)

julia> ligand[43]
    4037   O1      T3     B        2      512  -22.568   81.625    3.159  1.00 36.59     1       -      4041

julia> protein[3684]
    3684  NE2     HIS     B      435      472  -21.539   82.145    5.686  1.00 44.44     1       -      3686

julia> distance(ligand[43],protein[3684])
2.7775834820937417
PDBToolsBase.closest — Function
closest(x,y)

Computes the minimum distance between two sets of atoms and returns the indices of the atoms and their distance. Both vector of atoms or vectors of coordinates can be used as input.

Examples

julia> model = wget("1BSX");

julia> protein = select(model,"protein");

julia> ligand = select(model,"resname T3");

julia> closest(ligand,protein)
(43, 3684, 2.7775834820937417)

julia> ligand[43]
    4037   O1      T3     B        2      512  -22.568   81.625    3.159 36.59  1.00     1       -      4041

julia> closest(ligand[43],protein)
(1, 3684, 2.7775834820937417)

julia> x = positions(protein)
3994-element Vector{SVector{3, Float64}}:
 [52.884, 24.022, 35.587]
 [52.916, 24.598, 36.993]
 ⋮
 [-46.887, 86.925, 13.235]
 [-47.164, 83.593, 15.25]

julia> closest(ligand,x)
(43, 3684, 2.7775834820937417)
source

Maximum and minimum coordinates of the atoms

Use maxmin(atoms), or maxmin(atoms,"resname CA"), for example:

julia> using PDBTools, LazyArtifacts

julia> atoms = read_pdb(PDBTools.test_file("small.pdb"));

julia> maxmin(atoms, "residue > 1")
 Minimum atom coordinates: xmin = [-6.974, -16.785, -10.863]
 Maximum atom coordinates: xmax = [-1.94, -9.552, -3.844]
 Length in each direction: xlength = [5.034000000000001, 7.2330000000000005, 7.019]

m is a structure containing the three vectors with minimum and maximum coordinates, and lengths.

PDBToolsBase.maxmin — Function
maxmin(atoms::AbstractVector{<:Atom}; selection)

Returns the maximum and minimum coordinates of an atom vector, and the length (maximum minus minimum) in each direction.

Example

julia> protein = wget("1LBD");

julia> maxmin(protein)
 
 Minimum atom coordinates: xmin = [-29.301, 57.178, 45.668]
 Maximum atom coordinates: xmax = [47.147, 99.383, 86.886]
 Length in each direction: xlength = [76.448, 42.205, 41.217999999999996]
source

Read and convert unit cells

PDBToolsBase.read_unitcell — Function
read_unitcell(file::AbstractString)

Reads the lattice parameters of unitcell from a PDB (CRYST1 field) or mmCIF file, and converts it to a unitcell matrix with the lattice_to_matrix function. The unitcell matrix contains the lattice vectors as the columns of the matrix.

Example

julia> using PDBTools

julia> m = read_unitcell(PDBTools.test_file("pbc.pdb"))
3×3 StaticArraysCore.SMatrix{3, 3, Float32, 9} with indices SOneTo(3)×SOneTo(3):
 85.0   0.0   0.0
  0.0  85.0   0.0
  0.0   0.0  85.0

julia> matrix_to_lattice(m)
(a = 85.0f0, b = 85.0f0, c = 85.0f0, α = 90.0f0, β = 90.0f0, γ = 90.0f0)
source
PDBToolsBase.lattice_to_matrix — Function
lattice_to_matrix(a, b, c, α, β, γ)

Converts unit cell lattice parameters and convert them to a 3x3 unit cell matrix (orthogonalization matrix), where the lattice vectors are the columns of the matrix.

The resulting matrix has the lattice vectors as its columns, with vector 'a' aligned along the x-axis and vector 'b' in the xy-plane. This matrix can be used to transform fractional coordinates to Cartesian coordinates.

Arguments

  • a::Real: Length of side a in Ångströms.
  • b::Real: Length of side b in Ångströms.
  • c::Real: Length of side c in Ångströms.
  • α::Real: Angle alpha in degrees.
  • β::Real: Angle beta in degrees.
  • γ::Real: Angle gamma in degrees.

Returns

  • A 3x3 static matrix representing the unit cell vectors.
source
PDBToolsBase.matrix_to_lattice — Function
matrix_to_lattice(M::AbstractMatrix)

Converts a 3x3 unit cell matrix where the lattice vectors are the columns, back into the six lattice parameters (sides a, b, c and angles α, β, γ).

Arguments

  • M::AbstractMatrix: A 3x3 matrix where columns are the lattice vectors.

Returns

  • NamedTuple: A named tuple containing the six parameters: (a, b, c, α, β, γ). Lengths are in the matrix's original units (typically Ångströms), and angles are in degrees.
source

Periodic images

PDBToolsBase.wrap — Function
wrap(x, xref, unit_cell_matrix::SMatrix{N,N,T}) where {N,T}
wrap(x, xref, sides::AbstractVector)

Wraps the coordinates of point x such that it is the minimum image relative to xref. The unit cell may be given a a static matrix of size (N,N) or as a vector of length N.

source
PDBToolsBase.wrap_to_first — Function
wrap_to_first(x, unit_cell_matrix)

Wraps the coordinates of point x such that the returning coordinates are in the first unit cell with all-positive coordinates. The unit cell has to be a matrix of size (N,N).

Example

julia> using PDBTools: wrap_to_first

julia> uc = [10.0 0.0 0.0; 0.0 10.0 0.0; 0.0 0.0 10.0]
3×3 Matrix{Float64}:
 10.0   0.0   0.0
  0.0  10.0   0.0
  0.0   0.0  10.0

julia> wrap_to_first([15.0, 13.0, 2.0], uc)
3-element Vector{Float64}:
 5.0
 3.0000000000000004
 2.0
source

Structural alignment

PDBToolsBase.align — Function
align(x, y; mass=nothing)
align!(x, y; mass=nothing)

Aligns two structures (sets of points in 3D space). Solves the "Procrustes" problem, which is to find the best translation, and rotation, that aligns the two structures, minimizing the RMSD between them.

Structures are expected to be of the same size, and the correspondence is assumed from the vector indices.

align returns a new vector containing the coordinates of x aligned to y. align! modifies the input vector x in place.

source
PDBToolsBase.align! — Function
align(x, y; mass=nothing)
align!(x, y; mass=nothing)

Aligns two structures (sets of points in 3D space). Solves the "Procrustes" problem, which is to find the best translation, and rotation, that aligns the two structures, minimizing the RMSD between them.

Structures are expected to be of the same size, and the correspondence is assumed from the vector indices.

align returns a new vector containing the coordinates of x aligned to y. align! modifies the input vector x in place.

source
PDBToolsBase.rmsd — Function
rmsd(x::AbstractVector,y::AbstractVector)

Calculate the root mean square deviation between two vectors of coordinates.

Arguments

  • x::AbstractVector: A vector of coordinates.
  • y::AbstractVector: A vector of coordinates.

Returns

  • rmsd::Real: The root mean square deviation between the two vectors.
julia> import PDBTools: rmsd

julia> x = [ [1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0] ];

julia> y = [ [2.0, 3.0, 4.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0] ];

julia> rmsd(x, y)
1.0
source
PDBToolsBase.alignment_movements — Function
alignment_movements(
    x::AbstractVector{<:AbstractVector},
    y::AbstractVector{<:AbstractVector};
    mass=nothing,
    xm=zeros(3, length(x)),
    xp=zeros(3, length(x)),
)

Returns cmx, cmy, and rotation_matrix, necessary to translate and rotate y to minimize the RMSD relative to x.

Can be used to obtain the movement that aligns two sets of points, of the same size, and apply these movements to another set of points.

source
PDBToolsBase.apply_alignment_transformation! — Function
apply_alignment_transformation!(x, cmx, cmy, rotation_matrix)

Translates and rotates x such that the coordinates cmx are moved to cmy, and such apply the rotation defined in rotation_matrix.

source