Skip to content

Person 2: Hollow-based cavity detection (Python 3) #5

Description

@amruthesht

Summary

Upgrade cavity/solvent-accessibility features from the current convex-hull proxy to a Hollow-based pore/cavity detection pipeline. This is Person 2 workplan task 1 (stretch goal). Can be started without Person 1's curated annotations, but binding-site residue definitions may be refined later when Josh delivers ligand/binding-site data.

Background

Current implementation (confostate/features/cavity.py):

  • cavity_volume — convex hull of binding-pocket atoms (approximate)
  • cavity_accessibility_in / cavity_accessibility_out — simple slab-based CA exposure proxy

Workplan calls for Hollow-style structural hole filling:

  1. Initialize from binding site (nearest-neighbor graph of cavity centers)
  2. Extract pore features: path count, caliber / transition path metrics
  3. Original Hollow is Python 2.7 — needs a Python 3 rewrite or alternative

Binding site is currently defined by LEUT_BINDING_SITE_RESIDUES in cavity.py (literature-based). Sufficient to start; Person 1 may refine later.

Goals

Replace or supplement convex-hull cavity metrics with geometry derived from detected internal cavities/pores, improving discrimination between inward-open, outward-open, and occluded LeuT conformations.

Tasks

Phase 1 — Research & spike

  • Review original Hollow algorithm and outputs (volume, paths, caliber)
  • Evaluate implementation options:
    • Python 3 port of Hollow
    • Alternative (e.g. grid-based cavity detection, fpocket, custom MDAnalysis + scipy)
  • Document chosen approach in Plans/hollow-cavity-plan.md
  • Prototype on 2–3 LeuT PDBs (e.g. 3F3E OF, 3F3A IF, 3F4J occluded)

Phase 2 — Implementation

  • Implement cavity detection module (e.g. extend cavity.py or confostate/features/hollow.py)
  • Initialize search from binding-site center / LEUT_BINDING_SITE_RESIDUES
  • Extract features (minimum):
    • cavity_volume (Hollow-based, or clearly named e.g. cavity_hollow_volume)
    • cavity_accessibility_in / cavity_accessibility_out (path-based if possible)
  • Stretch features from workplan:
    • Number of paths through cavity
    • Minimum caliber / bottleneck radius along paths
  • Integrate into extract_features() via pipeline.py
  • Keep convex-hull features as fallback if Hollow fails on a structure

Phase 3 — Tests & docs

  • Unit tests on known LeuT structures (volume > 0, IF vs OF show sensible differences)
  • Update docs/features.md with new cavity feature definitions
  • Note dependency on binding-site residues; flag if Person 1 updates them

Acceptance criteria

  • Cavity features computed from PDB coordinates without annotations CSV
  • pytest passes including new cavity tests
  • extract_features() returns Hollow-based metrics for LeuT structures in input/
  • Approach documented; limitations vs convex-hull baseline stated clearly
  • Works on Python 3.9+ (project minimum)

Dependencies

Dependency Blocking? Notes
Person 1 annotations No Uses PDB + hardcoded binding site
Person 1 binding-site refinement No (may require re-tuning later) Coordinate via Tier 2 sync
Person 1 OPM data No Orientation already computed separately
Tier 1 (domain deltas) No Recommended to land first

Out of scope

  • RCSB metadata fetch (Person 1)
  • OPM integration (Person 1)
  • Symmetry module (Tier 5)
  • Full solvent-accessible surface area (SASA) unless trivial add-on

Risks

  • Effort: Largest remaining Person 2 item (days, not hours)
  • Rework: Binding-site definition may change when Person 1 curates ligand data
  • Binary dependency: If Hollow can't be ported cleanly, fallback library needs team buy-in

Files likely touched

  • confostate/features/cavity.py (and/or new hollow.py)
  • confostate/features/pipeline.py
  • tests/test_features.py
  • docs/features.md
  • Plans/hollow-cavity-plan.md
  • pyproject.toml (if new dependency)

Test plan

pip install -e ".[dev]"
python scripts/download_structures.py --codes 3F3E 3F3A 3F4J --output-dir input
pytest tests/test_features.py -v -k cavity
python -c "
from confostate.features import extract_features
for pdb in ['3F3E', '3F3A', '3F4J']:
    f = extract_features(f'input/{pdb}.pdb', reference_dir='input')
    print(pdb, f.get('cavity_volume'), f.get('cavity_accessibility_in'), f.get('cavity_accessibility_out'))
"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions