Dihedrals and Ramachandran plots

Dihedral angles can be computed with the dihedral function, and an application of this function is the computation of Ramachandran plots.

MolSimToolkitShared.dihedralFunction
dihedral(at1::Atom, at2::Atom, at3::Atom, at4::Atom)

Computes the dihedral angle given four atoms of type PDBTools.Atom.

Example

julia> using PDBTools

julia> pdb = read_pdb(PDBTools.TESTPDB);

julia> C1 = pdb[11]; N2 = pdb[13]; CA2 = pdb[15]; C2 = pdb[22];

julia> phi = dihedral(C1, N2, CA2, C2) 
-36.70359f0
source
PDBTools.RamachandranType
Ramachandran(prot::AbstractVector{<:PDBTools.Atom})
Ramachandran # type

The Ramachandran function receives a vector of atoms of a protein and and returns a Ramachandran object, with two fields phi and psi, containing the lists of corresponding angles, that is:

  • phi: C(-1) - N - CA - C
  • psi: N - CA - C - N(+1)

If any of the above atoms is missing, the function errors. The residues are expected to belong to a single chain and consecutive.

The resulting Ramachandran object can be plotted with the Plots.scatter function.

Example

julia> using PDBTools

julia> prot = read_pdb(PDBTools.TESTPDB, "protein");

julia> ram = Ramachandran(prot)
Ramachandran data: phi, psi vectors with 102 angles.
source
Plots.scatterMethod
scatter(ram::Ramachandran; kargs...)

Creates a Ramachandran plot given a Ramachandran object.

Arguments

  • ram::Ramachandran: the Ramachandran object, containing ϕ and ψ angles, resulting from the the Ramachandan function.

All other arguments are default keywords of Plots.scatter and can be adjusted to customize the plot.

Example

julia> using PDBTools, Plots

julia> prot = read_pdb(PDBTools.TESTPDB, "protein");

julia> ram = Ramachandran(prot)
Ramachandran data: phi, psi vectors with 102 angles.

julia> # plt = scatter(map) # uncomment to plot
source

Dihedral angles

The dihedral function computes the dihedral angle given four atoms:

julia> using PDBTools, Plots

julia> prot = read_pdb(PDBTools.TESTPDB, "protein");

julia> dihedral(prot[1], prot[5], prot[11], prot[13])
64.07296f0

Ramachandran plot

The Ramachandran function and object are used to compute and plot Ramachandran plots for a protein structure. The call to Ramachandran(vec) where vec is a vector of Atoms returns a Ramachandran object, with fields phi and psi, containing the list of dihedral angles:

using PDBTools
prot = read_pdb(PDBTools.TESTPDB, "protein");
ram = Ramachandran(prot)
Ramachandran data: phi, psi vectors with 102 angles.

Given the ram::Ramachandran object, the scatter function from Plots can be used to produce the Ramachandran plot:

using Plots
scatter(ram)
Example block output

All scatter parameters can be customized using the Plots keyword syntax.

Setting backbone dihedral angles

The set_phi! and set_psi! functions set the phi and psi backbone dihedral angles of a protein to given target values, rigidly rotating the corresponding downstream fragment of the chain (side chain, and every atom from that point to the C-terminus) around the relevant backbone bond. Rotations are applied residue by residue, from the first to the last, so setting phi does not disturb any previously-set psi angle, and vice versa.

PDBTools.set_phi!Function
set_phi!(atoms::AbstractVector{<:Atom}, phi_vec::AbstractVector{<:Real}; unit="rad")

Sets the phi backbone dihedral angles (C(-1) - N - CA - C) of a protein, given a vector of target angles. phi_vec must have length(residues) - 1 elements, one for every residue but the first (in sequential order), where residues = collect(eachresidue(atoms)).

Angles are interpreted as radians by default (unit="rad"); pass unit="deg" to provide degrees instead.

Setting the phi angle of a residue rigidly rotates every atom attached to its CA, other than N - that is, its side chain, its C and O (and OXT, if terminal) atoms, and all atoms of the following residues - around the N-CA bond, so that the new phi angle matches the requested value. Rotations are applied residue by residue, from the first to the last, so that previously-set phi angles are not disturbed by later ones.

atoms must belong to a single protein chain, and contain the N, CA, and C atoms needed to define every phi angle to be set, or the function throws an ArgumentError.

Example

julia> using PDBTools

julia> prot = read_pdb(PDBTools.TESTPDB, "protein");

julia> nres = length(collect(eachresidue(prot)));

julia> set_phi!(prot, fill(-60.0, nres - 1); unit="deg");

julia> ram = Ramachandran(prot);

julia> all(≈(-60.0; atol=1e-3), ram.phi)
true
source
PDBTools.set_psi!Function
set_psi!(atoms::AbstractVector{<:Atom}, psi_vec::AbstractVector{<:Real}; unit="rad")

Sets the psi backbone dihedral angles (N - CA - C - N(+1)) of a protein, given a vector of target angles. psi_vec must have length(residues) - 1 elements, one for every residue but the last (in sequential order), where residues = collect(eachresidue(atoms)).

Angles are interpreted as radians by default (unit="rad"); pass unit="deg" to provide degrees instead.

Setting the psi angle of a residue rigidly rotates every atom attached to its C, other than CA - that is, its O atom and all atoms of the following residues - around the CA-C bond, so that the new psi angle matches the requested value. Rotations are applied residue by residue, from the first to the last, so that previously-set psi (and phi) angles are not disturbed by later ones.

atoms must belong to a single protein chain, and contain the N, CA, C, and O atoms needed to define every psi angle to be set, or the function throws an ArgumentError.

Example

julia> using PDBTools

julia> prot = read_pdb(PDBTools.TESTPDB, "protein");

julia> nres = length(collect(eachresidue(prot)));

julia> set_psi!(prot, fill(140.0, nres - 1); unit="deg");

julia> ram = Ramachandran(prot);

julia> all(≈(140.0; atol=1e-3), ram.psi)
true
source

Both functions require atoms to belong to a single protein chain, with the backbone atoms needed to define every dihedral to be set. Angles are given in radians by default:

using PDBTools
prot = read_pdb(PDBTools.TESTPDB, "protein");
nres = length(collect(eachresidue(prot)));
set_phi!(prot, fill(-60.0, nres - 1); unit="deg")
set_psi!(prot, fill(-45.0, nres - 1); unit="deg")
scatter(Ramachandran(prot))
Example block output

Fully extended chain

extended_chain! sets every phi and psi angle of a protein to 180°, producing the fully extended (all-trans, "C5") backbone conformation - for example, to use as an explicit model of the unfolded state (as required by the MTRecord transfer model). extended_chain is the non-mutating version, returning a new, independent vector of atoms:

PDBTools.extended_chain!Function
extended_chain!(atoms::AbstractVector{<:Atom})

Sets every phi and psi backbone dihedral angle of atoms to 180°, producing the fully extended (all-trans, "C5") conformation, in place.

atoms must satisfy the same requirements as set_phi!/set_psi! (single protein chain, required backbone atoms present).

source
PDBTools.extended_chainFunction
extended_chain(atoms::AbstractVector{<:Atom})

Non-mutating version of extended_chain!: returns a new vector of atoms, a copy of atoms with every phi and psi backbone dihedral angle set to 180° (the fully extended conformation).

source
ext = extended_chain(prot)
scatter(Ramachandran(ext))
Example block output

Check the stereochemistry of protein residues

PDBTools.zetaFunction
zeta(r::Residue)

Computes the Cα chirality (zeta "virtual" torsion angle - Cα-N-C-Cβ).

Returns the torsion angle or NaN if the residue is not recognized a protein residue or if its a Gly residue. Expected values are 33.9 ± 3.5 degrees (for one standard deviation). Also see the zeta_check function.

Example

julia> using PDBTools

julia> protein = select(read_pdb(PDBTools.TESTPDB), "protein");

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

julia> zeta(residues[1])
33.67202f0
source
PDBTools.zeta_checkFunction
zeta_check(r::Residue; nsigma=2)

Checks if the Cα chirality falls into expected ranges. See the zeta function for further information. The expected mean is 33.9 degrees with a standard deviation of 3.5 degrees. By default, nsigma=2, implying that the function returns true if the torsion falls within two standard deviations from the mean.

See: https://www.ebi.ac.uk/thornton-srv/software/PROCHECK/manual/manappa.html

Example

julia> using PDBTools

julia> protein = select(read_pdb(PDBTools.TESTPDB), "protein");

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

julia> zeta_check(residues[1])
true
source