Shape Properties#
Shape properties are measurements of the shape of a protein when it is viewed from a specific orientation. Examples include the projected area, perimeter, bounding-box size, and shape moments.
Before a shape property can be calculated, the corresponding shape must
already have been calculated by a ShapeCalculator, as described in
Shapes.
Using Shape Properties#
Before calculating a shape property, we first need to load a protein and
calculate a shape for it. Here, we use the 8JXW structure, as
described in Loading Protein, and calculate an alpha shape for
each sampled orientation. See Shapes for more details on shape
calculation.
import ProteoTwirl.ProteinRotation as pt
protein_structure = pt.ProteinRotation(
protein = "Test_Data/8JXW_H.pdb",
selection = "protein and segid E and not element H",
base_rotation = "principle",
center_selection = True,
)
protein_structure.add_property(
property = "Alphashape",
alpha = 0.5,
hole_fill = 0.1,
rotation_res = 64,
use_default = False,
)
# Added Alpha_Shape_50_HF10
To calculate a shape property, specify the name of the previously
calculated shape using shape_prop_name. The rotation settings should
match those used for the shape calculation, including rotation_res,
rotation_range, and related options, so that each property value
corresponds to the same sampled orientation.
protein_structure.add_property(
property = "shape.area",
shape_prop_name = "Alpha_Shape_50_HF10",
rotation_res = 64,
use_default = False,
)
# Added Alpha_Shape_50_HF10_area
The first shape added to a ProteinRotation object is set as the
default shape. If a shape property should be calculated for this default
shape, shape_prop_name does not need to be specified. See
Default Shape for more information on default shapes.
Available Shape Properties#
ProteoTwirl includes several built-in shape properties. These are listed below.
Property |
Name |
Return Type |
Description |
|---|---|---|---|
Area |
|
|
Calculates the area of the shape. |
Perimeter |
|
|
Calculates the perimeter length of the shape. |
Bounding X Length |
|
|
Calculates the x-axis span of the smallest bounding box containing the shape. |
Bounding Y Length |
|
|
Calculates the y-axis span of the smallest bounding box containing the shape. |
Number of Components |
|
|
Counts how many disconnected polygons the shape consists of. |
First Hu moment |
|
|
Calculates the first Hu moment of the shape. |
Second Hu moment |
|
|
Calculates the second Hu moment of the shape. |
Third Hu moment |
|
|
Calculates the third Hu moment of the shape. |
Fourth Hu moment |
|
|
Calculates the fourth Hu moment of the shape. |
Fifth Hu moment |
|
|
Calculates the fifth Hu moment of the shape. |
Sixth Hu moment |
|
|
Calculates the sixth Hu moment of the shape. |
Seventh Hu moment |
|
|
Calculates the seventh Hu moment of the shape. |
All Hu moments |
|
|
Calculates all seven Hu moments of the shape. |
Custom Shape Property#
You can define a custom shape property in ProteoTwirl by defining a function that takes a Shapely geometry object as input and returns a value.
Here, we implement a simple circularity measure:
A perfect circle has a circularity of 1. Less circular shapes have
lower values.
import numpy as np
from shapely.geometry import MultiPolygon
def circularity(shape, **kwargs):
polygon = shape
# If the shape contains multiple disconnected polygons,
# calculate circularity for the largest component.
if isinstance(shape, MultiPolygon):
polygon = max(shape.geoms, key=lambda geom: geom.area)
# Avoid division by zero for empty or degenerate shapes.
if polygon.is_empty or polygon.length == 0:
return np.nan
return (4 * np.pi * polygon.area) / (polygon.length ** 2)
The easiest way to use this function as a shape property is to register it as a shape feature.
from ProteoTwirl.Properties.ShapeProperty import _register_shape_feature
_register_shape_feature("circularity", circularity)
The new property can then be calculated like any other shape property.
protein_structure.add_property(
property = "shape.circularity",
shape_prop_name = "Alpha_Shape_50_HF10",
rotation_res = 64,
use_default = False,
)
# Added Alpha_Shape_50_HF10_circularity
Finally, visualize the new property.
protein_structure.plot_property_3d(
"Alpha_Shape_50_HF10_circularity",
background="#14181e",
)