Skip to content

celalp/surfacepatcher

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SurfacePatcher

Protein surface comparison toolkit with multiple complementary methods for finding similar surface patches.

Features

  • Geodesic Patch Descriptors: High-resolution radial descriptors with biochemical feature weighting
  • Point Cloud Descriptors: FPFH, SHOT, and Zernike 3D moments for geometric comparison
  • Topological Descriptors: Persistent homology for multi-scale shape analysis
  • Hybrid Comparison: Weighted fusion of multiple methods with preset configurations

Installation

Create conda environment

# Create conda environment
conda env create -f environment.yml

# Activate environment
conda activate surfacepatcher

Install Package

# Clone or download the repository
cd surfacepatcher

# Install in development mode
pip install -e .

# Or install directly
pip install .

Install Dependencies

All Python dependencies will be installed automatically. If you need to install manually:

pip install -r requirements.txt

Note: Installing giotto-tda may require additional system dependencies. See giotto-tda installation guide.

Quick Start

1. Extract Surface Patches

from geodesic_patcher import GeodesicPatcher

# Initialize patcher
patcher = GeodesicPatcher()

# Extract patches from protein
patches = patcher(
    pdb_file="protein.pdb",
    chain_id=0,
    radius_angstrom=15,  # Patch radius
    M=36,                # Angular sampling (10° intervals)
    K=6                  # Radial sampling points
)

2. Compare Using Different Methods

Method 1: Geodesic Patch Comparison (Feature-Weighted)

from patch_comparison import PatchComparison

comparator = PatchComparison(
    patches1, 
    patches2,
    use_epitope_weights=True  # Optimized for epitope finding
)

distances, indices, keys1, keys2 = comparator.compute(batch_size=100)

Method 2: Point Cloud Geometric Descriptors

from pointcloud_comparison import PointCloudComparison

# Option A: FPFH descriptors
comparator = PointCloudComparison(
    patches1, patches2,
    descriptor_type='fpfh'
)

# Option B: Zernike 3D moments (rotation-invariant)
comparator = PointCloudComparison(
    patches1, patches2,
    descriptor_type='zernike',
    zernike_order=10,      # Polynomial order
    zernike_grid_size=32   # Voxel resolution
)

distances, keys1, keys2 = comparator.compute(distance_metric='euclidean')

Method 3: Topological Descriptors (Persistent Homology)

from topological_comparison import TopologicalComparison

comparator = TopologicalComparison(
    patches1, patches2,
    homology_dimensions=(0, 1, 2),  # H0, H1, H2
    max_edge_length=15.0,
    use_feature_filtration=True     # Include biochemical features
)

distances, keys1, keys2 = comparator.compute()

Method 4: Hybrid Comparison (Combine All Methods)

from hybrid_comparison import HybridComparison

# Compute with all three methods first
geodesic_results = geodesic_comparator.compute()
pointcloud_results = pointcloud_comparator.compute()
topological_results = topological_comparator.compute()

# Combine with hybrid approach
hybrid = HybridComparison(
    geodesic_results=geodesic_results,
    pointcloud_results=pointcloud_results,
    topological_results=topological_results,
    weights=HybridComparison.get_preset_weights('epitope'),
    fusion_method='weighted_sum'
)

hybrid_distances, keys1, keys2 = hybrid.compute()

# Get top matches
top_matches = hybrid.get_top_matches(n=10, method='hybrid')

# Analyze method agreement
correlations = hybrid.get_method_agreement()

Method Comparison

Method Best For Speed Key Features
Geodesic Detailed local patterns Medium High-res radial features, biochemistry
FPFH/SHOT Overall shape Fast Local geometric histograms
Zernike Global shape Medium Rotation-invariant moments
Topological Cavities & topology Slow Persistent homology (H0, H1, H2)
Hybrid Comprehensive analysis Slow Combines all methods

Configuration Options

Geodesic Patch Comparison

# Feature weight presets
PatchComparison.get_preset_weights('epitope')    # Antibody binding sites
PatchComparison.get_preset_weights('enzyme')     # Active sites
PatchComparison.get_preset_weights('interface')  # Protein-protein interfaces
PatchComparison.get_preset_weights('general')    # Equal weights

# Custom weights (order: shape_index, mean_curvature, electrostatic, 
#                        h_bond_donor, h_bond_acceptor, hydrophobicity)
custom_weights = [2.0, 1.5, 2.0, 1.8, 1.8, 1.2]
comparator = PatchComparison(patches1, patches2, feature_weights=custom_weights)

Point Cloud Descriptors

# Descriptor types
descriptor_type='fpfh'      # Fast Point Feature Histogram
descriptor_type='shot'      # Signature of Histograms of Orientations
descriptor_type='zernike'   # 3D Zernike moments
descriptor_type='all'       # Combine all three

# Zernike parameters
zernike_order=10           # Polynomial order (10-20 typical)
zernike_grid_size=32       # Voxel resolution (16=fast, 32=balanced, 64=detailed)

# Distance metrics
distance_metric='euclidean'  # L2 distance
distance_metric='cosine'     # Cosine similarity
distance_metric='chi2'       # Chi-square (for histograms)

Topological Descriptors

# Homology dimensions
homology_dimensions=(0, 1, 2)  # H0=components, H1=loops, H2=voids

# Filtration parameters
max_edge_length=15.0           # Maximum edge length for Vietoris-Rips
use_feature_filtration=True    # Include electrostatic/hydrophobic filtrations

Hybrid Comparison

# Fusion methods
fusion_method='weighted_sum'   # Weighted average of normalized distances
fusion_method='rank_fusion'    # Borda count on rankings
fusion_method='product'        # Geometric mean

# Weight presets
HybridComparison.get_preset_weights('balanced')         # Equal weights
HybridComparison.get_preset_weights('epitope')          # Optimized for epitopes
HybridComparison.get_preset_weights('shape_focused')    # Emphasize geometry
HybridComparison.get_preset_weights('topology_focused') # Emphasize topology

Recommendations for Epitope Finding

  1. Use Hybrid Approach with 'epitope' preset weights
  2. Emphasize:
    • Geodesic method (detailed biochemical features)
    • Topological method (cavity/protrusion detection)
  3. Descriptor Choice: Zernike for global shape + FPFH for local geometry
  4. Fusion: Use 'weighted_sum' or 'rank_fusion' for stable results
  5. Validation: Check method agreement with hybrid.get_method_agreement()

API Reference

GeodesicPatcher

patcher = GeodesicPatcher()
patches = patcher(
    pdb_file: str,           # Path to PDB file
    chain_id: int,           # Chain to process
    radius_angstrom: int,    # Patch radius in Angstroms
    M: int,                  # Number of angular rays (360/M = angle)
    K: int,                  # Radial sampling points
    cleanup: bool = True     # Remove temporary files
)

PatchComparison

comparator = PatchComparison(
    patches1: ProteinPatches,
    patches2: ProteinPatches,
    feature_weights: Optional[List[float]] = None,
    use_epitope_weights: bool = True
)

distances, indices, keys1, keys2 = comparator.compute(batch_size: int = 100)

PointCloudComparison

comparator = PointCloudComparison(
    patches1: ProteinPatches,
    patches2: ProteinPatches,
    descriptor_type: str = 'fpfh',  # 'fpfh', 'shot', 'zernike', 'all'
    zernike_order: int = 10,
    zernike_grid_size: int = 32
)

distances, keys1, keys2 = comparator.compute(distance_metric: str = 'euclidean')

TopologicalComparison

comparator = TopologicalComparison(
    patches1: ProteinPatches,
    patches2: ProteinPatches,
    homology_dimensions: Tuple[int, ...] = (0, 1, 2),
    max_edge_length: float = 15.0,
    use_feature_filtration: bool = True
)

distances, keys1, keys2 = comparator.compute(distance_metric: str = 'euclidean')

HybridComparison

hybrid = HybridComparison(
    geodesic_results: Optional[Tuple] = None,
    pointcloud_results: Optional[Tuple] = None,
    topological_results: Optional[Tuple] = None,
    weights: Optional[Dict[str, float]] = None,
    fusion_method: str = 'weighted_sum'
)

distances, keys1, keys2 = hybrid.compute()
top_matches = hybrid.get_top_matches(n: int = 10, method: str = 'hybrid')
correlations = hybrid.get_method_agreement()

Troubleshooting

MSMS not found

# Ensure MSMS is in PATH
which msms
# If not found, add to PATH or install

giotto-tda installation issues

# Install system dependencies first (Ubuntu/Debian)
sudo apt-get install build-essential cmake

# Then install giotto-tda
pip install giotto-tda

Out of memory errors

# Reduce batch size for geodesic comparison
comparator.compute(batch_size=50)

# Reduce grid size for Zernike
zernike_grid_size=16

# Process fewer patches at once

Citation

If you use this package in your research, please cite:

@software{surfacepatcher,
  title = {SurfacePatcher: Multi-Method Protein Surface Comparison},
  author = {Alper Celik},
  year = {2025},
  url = {https://github.com/celalp/surfacepatcher}
}

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

Support

For questions or issues, please open an issue on GitHub or contact [alper.celik@sickkids.ca]

About

Separate the surface of a protein into segments of circles of r radius and compare each segment to other segments

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages