← Về thư mục
📄 / / profiles / r-and-d / raw_evidence / OpenAI4S / skills / bioskills / bio-chemoinformatics-pharmacophore-modeling / SKILL.md

name: bio-pharmacophore-modeling description: 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. origin: openai4s category: bioskills/chemoinformatics metadata: tool_type: python primary_tool: RDKit third_party: name: GPTomics/bioSkills repository: https://github.com/GPTomics/bioSkills commit: d91ed3d563019e649dc854c56ccd62551359488a license: MIT


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

Feature Common shorthand Definition Geometric tolerance
H-bond donor D -OH, -NH 1.0-1.5 Å
H-bond acceptor A sp2 O / N (lone pair) 1.0-1.5 Å
Hydrophobe H sp3 C / aromatic ring centroid 1.5-2.0 Å
Aromatic ring R Aromatic ring centroid + normal 1.0-1.5 Å
Positive ionizable P -NH3+, -NR3+ 1.0-1.5 Å
Negative ionizable N -COO-, -SO3- 1.0-1.5 Å
Halogen X Cl, Br, I (halogen bond donor) 1.0-1.5 Å
Metal coordination M sp/sp2 N/O near metal 0.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

Method Origin Use case Fails when
Ligand-based (LBP) Catalyst, MOE, RDKit Pharm3D Multiple actives, no crystal <3 actives; flexible actives
Receptor-based (RBP) apo2ph4, LigandScout, PLIP Co-crystal or a defined apo pocket Uncertain pocket conformation
Common pharmacophore Validated alignment/feature-consensus workflow; RDKit can represent and query the resulting model Consensus from active set Diverse actives or uncertain bioactive conformers confound alignment
Pocket-conditioned generation (PharmacoForge) Flynn et al. 2025 Generate candidate pharmacophores from a protein pocket Does not directly generate molecules; pretrained model required
Active learning pharmacophore Catalyst variant Iterative refinement Custom; not standard

Decision Tree by Scenario

Scenario Method Tools
Co-crystal structure available Interaction-derived receptor model PLIP or LigandScout + Pharmit
Apo structure with a defined pocket Apo receptor model apo2ph4; export LigandScout PML
Multiple active compounds, no crystal Ligand-based common pharmacophore Alignment plus consensus-feature derivation in validated custom or external tooling; RDKit Pharm3D can apply the resulting model
Single active compound Single-conformer pharmacophore RDKit Pharm3D from bioactive conformer
Scaffold hopping prospective Receptor-based + shape filter apo2ph4 or interaction-derived model + shape search
Cross-target SAR transfer Common pharmacophore across targets Manual + LigandScout
Generate pocket-conditioned pharmacophores PharmacoForge Diffusion model followed by library retrieval
Library pre-filtering Pharmacophore screen Pharmit 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

Method Captures Best for
ECFP4 Tanimoto Local atom environments Lead optimization (same series)
FCFP4 Tanimoto Pharmacophore-equivalent atoms Loose similarity in series
Shape similarity (ROCS) 3D shape volume Scaffold hopping by shape
Pharmacophore Discrete features in space Scaffold hopping with feature specificity
Combined (Tanimoto + shape) Multi-objective Production 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

Aspect Ligand-based Receptor-based
Data needed Multiple actives with defensible conformers/alignment A defined pocket, optionally with a co-crystal ligand
Main bias Known active chemotypes, conformer choice, and alignment Pocket structure, protonation, retained waters, and interaction-detection/modeling rules
Hit-set behavior Depends on feature abstraction and tolerances Depends on selected pocket interactions, excluded volumes, and tolerances
Confidence evidence Retrospective recovery across held-out actives/inactives Recovery 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

Symptom Cause Fix
Pharm3D.EmbedPharmacophore fails Bounds matrix infeasible Review/loosen justified bounds and, when more attempts are warranted, increase the documented count argument; inspect n_failed
Pharmacophore matches everything Too few features Add features; tighten tolerances
Pharmacophore matches nothing Too many features or tight bounds Reduce feature count; loosen tolerances
BaseFeatures.fdef not found RDKit installation issue Check from rdkit.RDPaths import RDDataDir
Pharmacophore-conformer mismatch Wrong conformer used Use bioactive conformer from crystal
Pharmit search timeout Library too large Pre-filter by 2D fingerprint Tanimoto
apo2ph4 PML has no useful model No robust pocket hot spots at selected settings Recheck pocket definition and documented thresholds; inspect alternative models

References