bio-pharmacophore-modeling

SkillSearch

Builds and applies 3D pharmacophore models using RDKit Pharm3D, the apo2ph4 receptor-based workflow (Heider et al. 2023), Pharmer / Pharmit for search, and PharmacoForge for protein-pocket-conditioned pharmacophore generation (Flynn et al. 2025), covering ligand-based pharmacophores from active-set alignment and receptor-based pharmacophores from binding-pocket geometry. Explicitly handles feature types, geometric tolerances, partial matching, and pharmacophore-based virtual screening. Use when identifying scaffold-hopping candidates, building shape-and-feature search queries, or transferring SAR across chemotypes.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the bio-pharmacophore-modeling skill

What this skill tells your AI

The instructions your AI receives, as published by pku-yuangroup/openai4s in skills/bioskills/bio-chemoinformatics-pharmacophore-modeling/SKILL.md and read by ahel’s review.

Version Compatibility

Reference examples tested with: RDKit 2024.09+, Pharmit web service, and PLIP 2.4+ (interaction analysis). Verify the deployed Pharmit/Pharmer interface and query format before automation.

Before using code patterns, verify installed versions match. If versions differ:

  • Python: pip show rdkit then help(rdkit.Chem.Pharm3D) to check signatures

If code throws ImportError, AttributeError, or TypeError, introspect the installed package and adapt the example to match the actual API rather than retrying.

Pharmacophore Modeling

Build 3D pharmacophore queries that capture the essential interaction features of a ligand-target binding event. A pharmacophore is the spatial arrangement of pharmacophore features (donor, acceptor, hydrophobe, aromatic, charged) sufficient for activity, abstracted from any specific chemotype. Use pharmacophores for scaffold hopping, virtual-screening prefilters, and cross-target SAR transfer. Derive interaction features directly from a co-crystal when available, use apo2ph4 to derive models from an apo pocket (Heider et al. 2023), or align known actives for a ligand-based model. PharmacoForge generates candidate 3D pharmacophores conditioned on a protein pocket; those pharmacophores can then retrieve matching molecules from a library (Flynn et al. 2025).

For 2D scaffold-based searches, see chemoinformatics/scaffold-analysis. For 3D shape similarity, see chemoinformatics/shape-similarity. For protein-ligand interaction analysis, see chemoinformatics/virtual-screening.

Pharmacophore Feature Types

FeatureCommon shorthandDefinitionGeometric tolerance
H-bond donorD-OH, -NH1.0-1.5 Å
H-bond acceptorAsp2 O / N (lone pair)1.0-1.5 Å
HydrophobeHsp3 C / aromatic ring centroid1.5-2.0 Å
Aromatic ringRAromatic ring centroid + normal1.0-1.5 Å
Positive ionizableP-NH3+, -NR3+1.0-1.5 Å
Negative ionizableN-COO-, -SO3-1.0-1.5 Å
HalogenXCl, Br, I (halogen bond donor)1.0-1.5 Å
Metal coordinationMsp/sp2 N/O near metal0.5-1.0 Å

Tolerances are pharmacophore-feature distance windows in the search. Tighter tolerances = fewer hits but more specific.

The ranges in this table are repository starting heuristics, not universal feature tolerances. Set final bounds from aligned-feature variability, coordinate uncertainty, and retrospective validation for the selected search engine.

The one-letter labels above are human-readable shorthand, not RDKit API codes. RDKit's shipped BaseFeatures.fdef uses family names such as Donor, Acceptor, Hydrophobe, Aromatic, PosIonizable, and NegIonizable. Its default feature definitions do not provide every halogen-bond or metal-coordination model; add and validate project-specific feature definitions when those interactions matter.

Method Taxonomy

MethodOriginUse caseFails when
Ligand-based (LBP)Catalyst, MOE, RDKit Pharm3DMultiple actives, no crystal<3 actives; flexible actives
Receptor-based (RBP)apo2ph4, LigandScout, PLIPCo-crystal or a defined apo pocketUncertain pocket conformation
Common pharmacophoreValidated alignment/feature-consensus workflow; RDKit can represent and query the resulting modelConsensus from active setDiverse actives or uncertain bioactive conformers confound alignment
Pocket-conditioned generation (PharmacoForge)Flynn et al. 2025Generate candidate pharmacophores from a protein pocketDoes not directly generate molecules; pretrained model required
Active learning pharmacophoreCatalyst variantIterative refinementCustom; not standard

Decision Tree by Scenario

ScenarioMethodTools
Co-crystal structure availableInteraction-derived receptor modelPLIP or LigandScout + Pharmit
Apo structure with a defined pocketApo receptor modelapo2ph4; export LigandScout PML
Multiple active compounds, no crystalLigand-based common pharmacophoreAlignment plus consensus-feature derivation in validated custom or external tooling; RDKit Pharm3D can apply the resulting model
Single active compoundSingle-conformer pharmacophoreRDKit Pharm3D from bioactive conformer
Scaffold hopping prospectiveReceptor-based + shape filterapo2ph4 or interaction-derived model + shape search
Cross-target SAR transferCommon pharmacophore across targetsManual + LigandScout
Generate pocket-conditioned pharmacophoresPharmacoForgeDiffusion model followed by library retrieval
Library pre-filteringPharmacophore screenPharmit search

Ligand-Based Pharmacophore (RDKit Pharm3D)

Goal: Derive a common pharmacophore from aligned bioactive conformers, then apply that established model to candidate molecules.

Approach: Consensus derivation is a separate modeling step: select or generate plausible bioactive conformers, align them using a documented method, identify conserved feature correspondences, and estimate distance bounds or tolerances. RDKit does not provide a single EmbedPharmacophore call that performs those steps. EmbedPharmacophore instead generates conformations of a molecule that satisfy an already defined pharmacophore.

from rdkit import Chem, Geometry
from rdkit.Chem import ChemicalFeatures
from rdkit.Chem.Pharm3D import EmbedLib, Pharmacophore
from rdkit.RDPaths import RDDataDir
import os

fdef_file = os.path.join(RDDataDir, 'BaseFeatures.fdef')
factory = ChemicalFeatures.BuildFeatureFactory(fdef_file)

# This is an already defined model. Coordinates and bounds must come from a
# validated consensus-derivation workflow or another justified source. RDKit
# requires FreeChemicalFeature objects, not feature-family strings.
query_features = [
    ChemicalFeatures.FreeChemicalFeature(
        'Aromatic', Geometry.Point3D(0.0, 0.0, 0.0)),
    ChemicalFeatures.FreeChemicalFeature(
        'Donor', Geometry.Point3D(4.0, 0.0, 0.0)),
]
pharmacophore = Pharmacophore.Pharmacophore(query_features)
pharmacophore.setLowerBound(0, 1, 3.5)
pharmacophore.setUpperBound(0, 1, 5.0)

target = Chem.AddHs(Chem.MolFromSmiles('c1ccc(cc1)CCN'))
can_match, feature_matches = EmbedLib.MatchPharmacophoreToMol(
    target, factory, pharmacophore)
if can_match:
    atom_match = tuple(tuple(matches[0].GetAtomIds())
                       for matches in feature_matches)
    _, embeddings, n_failed = EmbedLib.EmbedPharmacophore(
        target, atom_match, pharmacophore, randomSeed=23, silent=True)

BaseFeatures.fdef (RDKit-shipped) defines feature SMARTS and is a useful starting feature taxonomy. The code above demonstrates applying an existing two-feature model; it does not infer a consensus model from active compounds.

Receptor-Based Pharmacophore (apo2ph4 workflow)

Goal: Derive a pharmacophore from a protein binding-pocket structure without requiring a bound ligand.

Approach: Identify donor, acceptor, and hydrophobic hot spots from apo-pocket geometry, cluster them, and assemble candidate pharmacophores. Heider et al. describe apo2ph4 in J. Chem. Inf. Model. 63:101-110 (2023). Use the source release's documented scripts and environment rather than assuming a packaged apo2ph4 command: the published workflow writes LigandScout PML output, not a generic .ph4 file. Treat conversion to Pharmit, Pharmer, MOE, or Phase as a separate, explicitly validated step because pharmacophore formats are not interchangeable.

When a co-crystal ligand is available, derive pharmacophore directly from the ligand binding pose: each ligand feature in contact with a complementary protein residue is part of the pharmacophore.

from plip.basic import config
from plip.structure.preparation import PDBComplex

mol_complex = PDBComplex()
mol_complex.load_pdb('complex.pdb')
mol_complex.analyze()

for site in mol_complex.interaction_sets.values():
    for interaction in site.all_itypes:
        # Objects are interaction-class-specific. Inspect the documented fields
        # for HydrophobicContact, HydrogenBond, PiStacking, SaltBridge, etc.;
        # there is no universal `.type` or `.ligatom.coords` interface.
        interaction_class = type(interaction).__name__
        print(interaction_class, interaction)

PLIP exposes typed interaction records with class-specific ligand/protein atoms and coordinates. Map those records to pharmacophore features explicitly and retain the interaction class and source atom identifiers.

Pharmacophore Search (Pharmit / Pharmer)

For library screening, configure feature types, centers, radii, and optional shape constraints in Pharmit, or use a Pharmer database and query produced in the format required by the installed release. Do not pass LigandScout PML or a vendor .ph4 file directly unless the selected interface documents that import path. Pharmit reported searching millions of conformers in seconds to minutes; actual runtime depends on query selectivity, database size, and deployment (Sunseri & Koes 2016).

Pharmacophore Quality Validation

Evaluate a pharmacophore by:

  1. Retrospective enrichment: a stated metric on target-relevant actives and inactives/decoys. DUD-E can provide a benchmark with known decoy-construction biases; COCONUT is a natural-products collection, not a target-specific active/decoy benchmark.
  2. Geometric tightness: feature distance variance across actives
  3. Selectivity: false positives in inactive set should be low
  4. Specific consistency: pharmacophore matches each active's bioactive conformer
def pharmacophore_enrichment(query_pharmacophore, actives, inactives,
                             matches_pharmacophore):
    """Return active/inactive match-rate enrichment for a supplied matcher."""
    if not actives or not inactives:
        raise ValueError('actives and inactives must both be non-empty')
    n_active_match = sum(
        bool(matches_pharmacophore(mol, query_pharmacophore))
        for mol in actives)
    n_inactive_match = sum(
        bool(matches_pharmacophore(mol, query_pharmacophore))
        for mol in inactives)
    active_rate = n_active_match / len(actives)
    inactive_rate = n_inactive_match / len(inactives)
    return float('inf') if inactive_rate == 0 else active_rate / inactive_rate

For this repository, enrichment >=5x may be used as a starting triage heuristic only after the active/decoy construction and matching policy are documented. Report the full metric and uncertainty, and calibrate the acceptance threshold on the project dataset.

Pocket-Conditioned Pharmacophore Generation (PharmacoForge)

PharmacoForge (Flynn et al. 2025) applies a diffusion model to a protein pocket and generates candidate 3D pharmacophores. It does not directly generate molecular structures from an input pharmacophore. The validated workflow is:

  1. Prepare the protein pocket in the representation required by the published PharmacoForge release.
  2. Sample and rank pocket-conditioned pharmacophores.
  3. Convert a selected pharmacophore into the query representation used by the search engine.
  4. Retrieve matching, purchasable compounds and evaluate them with docking, strain, and physical-validity checks.

The paper compares pharmacophore and downstream retrieval performance with other pocket-based approaches; it does not support a drug-likeness or novelty comparison with REINVENT.

Pharmacophore vs Shape vs 2D Fingerprint

MethodCapturesBest for
ECFP4 TanimotoLocal atom environmentsLead optimization (same series)
FCFP4 TanimotoPharmacophore-equivalent atomsLoose similarity in series
Shape similarity (ROCS)3D shape volumeScaffold hopping by shape
PharmacophoreDiscrete features in spaceScaffold hopping with feature specificity
Combined (Tanimoto + shape)Multi-objectiveProduction VS

Pharmacophore is more interpretable than shape: a hit explains why it matched (donor at position X, hydrophobe at position Y).

Per-Tool Failure Modes

Ligand-based -- diverse actives confound

Trigger: Active set spans multiple scaffolds with different bound conformations.

Mechanism: No common pharmacophore exists; algorithm forces non-consensus features.

Symptom: Pharmacophore matches no actives in retrospective.

Fix: Cluster actives by scaffold first; derive per-cluster pharmacophore.

Receptor-based -- apo structure

Trigger: Protein in apo form (no bound ligand).

Mechanism: Side-chain rotamers differ between apo and holo; "binding site" geometry is wrong.

Symptom: Pharmacophore inferred from apo doesn't match holo experimental data.

Fix: Use AlphaFold3 / Boltz-1 to predict holo conformation; derive pharmacophore from predicted holo.

Pharmacophore -- single conformer bias

Trigger: Active aligned to its first generated conformer, not bioactive conformer.

Mechanism: Crystal structure not available; generated conformer may not be the bound one.

Symptom: Pharmacophore inconsistent across runs (different starting conformer chosen).

Fix: Use conformer ensemble; align all to common scaffold; choose conformer most consistent with other actives.

Tolerance too tight

Trigger: Default geometric tolerance < 0.5 Å.

Mechanism: Real bioactive conformers have flexibility; rigid pharmacophore filters most molecules out.

Symptom: Search returns zero hits.

Fix: Use tolerance 1.0-1.5 Å for drug-like; up to 2 Å for flexible peptide-like.

Pharmacophore search misses bioisostere

Trigger: Bioisostere replacement (e.g., -COOH replaced by tetrazole).

Mechanism: Tetrazole functions as acid bioisostere but RDKit features may not classify identically.

Symptom: Known bioisosteric active not found.

Fix: Use ChemAxon-style bioisosteric feature equivalence; or pharmacophore feature class expansion (acid generic vs -COOH specific).

PLIP -- water bridge absent from output

Trigger: Bridging water between ligand donor and protein acceptor.

Mechanism: PLIP can report water bridges, but the required crystallographic water must be present in the input and satisfy its geometric criteria.

Symptom: Pharmacophore missing critical H-bond feature.

Fix: Retain relevant crystallographic waters, inspect PLIP water-bridge output, and review borderline geometry manually.

Reconciliation: Ligand-Based vs Receptor-Based

AspectLigand-basedReceptor-based
Data neededMultiple actives with defensible conformers/alignmentA defined pocket, optionally with a co-crystal ligand
Main biasKnown active chemotypes, conformer choice, and alignmentPocket structure, protonation, retained waters, and interaction-detection/modeling rules
Hit-set behaviorDepends on feature abstraction and tolerancesDepends on selected pocket interactions, excluded volumes, and tolerances
Confidence evidenceRetrospective recovery across held-out actives/inactivesRecovery of known interaction geometry and retrospective or prospective validation

Choose between ligand- and receptor-based models using the available structural/activity evidence and target-relevant validation. Neither approach is universally more reliable, diverse, or suitable for scaffold hopping.

Common Errors

SymptomCauseFix
Pharm3D.EmbedPharmacophore failsBounds matrix infeasibleReview/loosen justified bounds and, when more attempts are warranted, increase the documented count argument; inspect n_failed
Pharmacophore matches everythingToo few featuresAdd features; tighten tolerances
Pharmacophore matches nothingToo many features or tight boundsReduce feature count; loosen tolerances
BaseFeatures.fdef not foundRDKit installation issueCheck from rdkit.RDPaths import RDDataDir
Pharmacophore-conformer mismatchWrong conformer usedUse bioactive conformer from crystal
Pharmit search timeoutLibrary too largePre-filter by 2D fingerprint Tanimoto
apo2ph4 PML has no useful modelNo robust pocket hot spots at selected settingsRecheck pocket definition and documented thresholds; inspect alternative models

References

Related Skills

  • chemoinformatics/molecular-io - Parse molecules
  • chemoinformatics/conformer-generation - Generate 3D for pharmacophore
  • chemoinformatics/shape-similarity - 3D shape adjacent to pharmacophore
  • chemoinformatics/virtual-screening - Pharmacophore as docking pre-filter
  • chemoinformatics/scaffold-analysis - 2D scaffold-hopping context
  • chemoinformatics/generative-design - Generate or optimize molecules after pharmacophore-based retrieval
  • structural-biology/structure-io - PDB handling

Signals

GitHub stars
404
Forks
48
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
bio-pharmacophore-modeling
Source
github.com/pku-yuangroup/openai4s