Count Properties#

A count property assigns a value to each atom or residue in a protein and then aggregates those values, for example by taking their mean, sum, or minimum. For a count property to be angle-dependent, one or more selectors are usually needed. Otherwise, the property is aggregated over the same atoms or residues for every orientation, which will usually produce the same value for all angles.

Using Count Properties#

Before using a count property, we need to load a protein. Here, we use the 8JXW structure, as described in detail in Loading Protein.

Loading Protein#
import ProteoTwirl.ProteinRotation as pt

protein_structure = pt.ProteinRotation(
    protein                 = "Test_Data/8JXW_H.pdb",
    selection               = "protein and segid E",
    base_rotation           = "principle",
    center_selection        = True,
)

To use a count property in an angle-dependent way, we define a selector so that different atoms or residues can be included depending on the protein orientation. In this example, we analyze the hydropathy of the outside of the protein. We use the ExposedAtomSelector to select exposed atoms and then calculate the average hydropathy of the corresponding residues using the built-in count.Hydropathy property.

The agg_method argument controls how the selected values are aggregated. Here, we set agg_method="mean" to calculate the mean of the selected residue hydropathy values.

Calculating Average Hydropathy of Exposed Residues#
from ProteoTwirl.Selectors.Selector import ExposedAtomSelector

protein_structure.add_property(
    property        = "count.Hydropathy",
    agg_method      = "mean",
    rotation_res    = 128,
    use_default     = False,
    selectors       = [ExposedAtomSelector()],
)

Available Count Properties#

ProteoTwirl includes several amino-acid properties that can be used as count properties. The available built-in count properties are listed below.

Count Properties#

Property

Name

Return Type

Description

Source

Hydropathy Index

count.Hydropathy

float or None

Returns the hydropathy index of a residue. Returns None if the residue is unknown or has no assigned value.

Kyte & Doolittle 1982 (IMGT)

Hydropathy (Kyte-Doolittle)

count.Hydropathy_KD

float or None

Returns the Kyte-Doolittle hydropathy value of a residue. Returns None if the residue is unknown or has no assigned value.

Kyte & Doolittle 1982 (IMGT)

Hydropathy (Goldman-Engelman-Steitz)

count.Hydropathy_GES

float or None

Returns the Goldman-Engelman-Steitz hydropathy value of a residue. Returns None if the residue is unknown or has no assigned value.

Engelman et al. 1986 (IMGT)

Acid pKa

count.pKa_O

float or None

Returns the pKa of the residue carboxylic acid group. Returns None if the residue is unknown or has no assigned value.

McMurry Table 26-1

Amino pKa

count.pKa_N

float or None

Returns the pKa of the residue amino group. Returns None if the residue is unknown or has no assigned value.

McMurry Table 26-1

Side-Chain pKa

count.pKa_SS

float or None

Returns the pKa of the residue side chain. Returns None if the residue is unknown or has no assigned value.

McMurry Table 26-1

Isoelectric Point

count.pI

float or None

Returns the isoelectric point of the residue. Returns None if the residue is unknown or has no assigned value.

McMurry Table 26-1

Volume

count.Volume

float or None

Returns the volume of the residue. Returns None if the residue is unknown or has no assigned value.

Zamyatnin 1972 (IMGT)

Residue Name

count.Amino_Acid

str

Returns the name of the residue.

N/A

Custom Count Properties#

Defining a custom count property is straightforward. Two things need to be defined:

  1. whether the property is evaluated for atoms or residues, and

  2. a function that returns one value for each atom or residue.

In the example below, we define a count property for aromatic residues. The function returns 1 for aromatic residues and 0 for all other residues.

Define a Function for Aromaticity#
def is_aromatic(residue):
    aromatic_residue_names = {"PHE", "TRP", "TYR", "HIS"}

    if residue.resname in aromatic_residue_names:
        return 1

    return 0

The easiest way to use this as a count property is to add it to the property registry, as shown below.

Register the Aromaticity Count Property#
from ProteoTwirl.Properties.CountProperty import _register_count_property

_register_count_property(
    name            = "aromatic",
    count_feature   = is_aromatic,
    countable       = "Residue",
)

The new property can then be calculated like any other count property.

Calculate the Aromaticity Count Property#
protein_structure.add_property(
    property        = "count.aromatic",
    rotation_res    = 128,
    agg_method      = "mean",
    use_default     = False,
    selectors       = [ExposedAtomSelector()],
)

Because is_aromatic returns either 1 or 0, using agg_method="mean" gives the fraction of selected residues that are aromatic. To calculate the number of selected aromatic residues instead, use a summing aggregation method if supported.

The new property can then be visualized using its generated property name.

Plot the Aromaticity Count Property#
protein_structure.plot_property_3d(
    "mean__is_aromatic",
    background="#14181e",
)

The same setup can also be used for individual atoms instead of residues. In that case, the function should take an MDAnalysis Atom as input instead of an MDAnalysis Residue, and countable should be set to "Atom".