SDK reference

Structure Interactions & Confidence Metrics

Python SDK 2026.11.05 · generated package reference

On this pageOverviewComplete Local ExampleSupported Interaction TypesNormalized Output ColumnsLigand Templates and Atom OrderingMetal Coordination and Geometry DeviationExplicit Records in PDB FilespLDDT Distribution SummariesExplicit Limitations

The Neurosnap SDK provides a robust and flexible framework for identifying physical interactions within and between molecular entities, and for analyzing predicted structure confidence metrics.

These features are exposed through high-level orchestrators, legacy compatibility wrappers, and dedicated report containers.

Overview#

Declared versus detected#

A structure carries two tables of connectivity that a file may state outright:

  • Structure.bonds holds persistent topology, each row tagged with a BondType of COVALENT, DISULFIDE, METAL_COORDINATION, or OTHER.

  • Structure.interactions holds noncovalent contacts a file declared, each row tagged with an InteractionType of IONIC, HYDROGEN_BOND, SALT_BRIDGE, or OTHER_NONCOVALENT.

The analysis described on this page is separate from both. It detects interactions from geometry and chemistry and returns them as a report, leaving the two tables untouched. Where a detected interaction was also declared by the source file, its evidence is reported as explicit. The methods are named detect_* for that reason: structure.detect_interactions() computes a result, whereas structure.interactions is a stored table.

Interaction analysis allows you to detect various structural contacts and bonds based on classical, geometric, and heuristic rules:

  • Hydrogen Bonds: Identifies donor-acceptor pairings and attached hydrogens using distance and optional angle cutoffs.

  • Salt Bridges: Identifies ionic contacts between oppositely charged residue centers or formal charges on aligned ligands.

  • Disulfide Bonds: Detects covalent bonds between cysteine sulfur (SG) atoms.

  • Metal Coordination: Analyzes coordination geometry and deviations around metal centers.

  • Contacts & Clashes: Detects standard spatial proximity and steric clashes.

  • Covalent Candidates: Identifies cross-entity covalent bond candidates.

Complete Local Example#

The following example demonstrates how to parse a synthetic PDB file from an in-memory string, define interaction entities, perform the interaction analysis, and extract a pandas DataFrame of the results.

import io
import pandas as pd
from neurosnap.io.pdb import parse_pdb
from neurosnap.structure import analyze_interactions, InteractionEntity

# 1. Define synthetic PDB data in memory
pdb_data = """
ATOM      1  N   ALA A   1       0.000   0.000   0.000  1.00 20.00           N
ATOM      2  CA  ALA A   1       1.458   0.000   0.000  1.00 20.00           C
ATOM      3  C   ALA A   1       1.958   1.410   0.000  1.00 20.00           C
ATOM      4  O   ALA A   1       1.200   2.200   0.000  1.00 20.00           O
HETATM    5  C1  BEN B   2       5.000   0.000   0.000  1.00 20.00           C
HETATM    6  C2  BEN B   2       6.400   0.000   0.000  1.00 20.00           C
"""

# 2. Parse the PDB string into a Structure object
ensemble = parse_pdb(io.StringIO(pdb_data), return_type="ensemble")
structure = ensemble.first()

# 3. Define the interacting entities using structure atom indices
# Entity 1: The ALA residue (atoms 0 to 3)
entity1 = InteractionEntity(name="protein_residue", atom_indices=[0, 1, 2, 3])
# Entity 2: The BEN ligand (atoms 4 and 5)
entity2 = InteractionEntity(name="ligand", atom_indices=[4, 5])

# 4. Analyze interactions between the two entities
report = analyze_interactions(structure, entity1, entity2, interaction_types=["contact"])

# 5. Export findings to a pandas DataFrame
df = report.to_dataframe()
print(df[["interaction_id", "interaction_type", "entity1", "entity2", "distance_a"]])

Note

The parse_pdb function with return_type="ensemble" returns a StructureEnsemble object. Calling ensemble.first() retrieves the first Structure model from this ensemble for downstream single-model interaction analysis.

Supported Interaction Types#

The interaction detection rules, default cutoffs, required topology, and possible evidence levels are summarized below:

Supported Interaction Types#

Interaction Type

Default Cutoff

Required Topology

Possible Evidence Levels

hydrogen_bond

3.5 Å (donor-acceptor distance), >= 130.0° (donor-H-acceptor angle)

Nitrogen, Oxygen, or Sulfur donors/acceptors. Uses RDKit chemical feature factory definitions for non-polymer ligands.

explicit (declared in interactions), detected (hydrogen found), candidate (distance-only cutoff when include_candidates=True)

disulfide

2.2 Å

Cysteine residues with sulfur atoms (SG).

explicit (BondType.DISULFIDE in bonds), detected (any SG-SG bond), candidate (distance-only)

salt_bridge

4.0 Å

Charged residue centers (NZ for LYS, NH1/NH2 for ARG, positively charged HIS; OD1/OD2 for ASP, OE1/OE2 for GLU) or formal charges on aligned ligands.

explicit (declared in interactions), detected

metal_coordination

2.8 Å

Any element in neurosnap.constants.chemistry.METAL_ELEMENTS, with coordinating donor atoms (O, N, S).

explicit, detected, candidate

contact

4.5 Å

Any non-hydrogen atom (unless include_hydrogens=True).

distance_cutoff

vdw_contact

Sum of Bondi VDW radii + 0.5 Å

Any atom pairs.

vdw_contact

clash

Bondi VDW overlap >= 0.4 Å

Any cross-entity atom pairs.

vdw_overlap

vdw_clash

Gap < -0.4 Å

Any non-bonded atom pairs across the structure.

vdw_overlap

covalent

[0.8, 1.2] * sum of covalent radii

Any non-metal atom pairs.

explicit, candidate

Normalized Output Columns#

The pandas DataFrame returned by calling InteractionReport.to_dataframe() contains the following normalized columns:

Interaction DataFrame Columns#

Column Name

Type

Description

interaction_id

string

Unique, deterministically-assigned interaction identifier (e.g., int_1).

interaction_type

string

The type of interaction (e.g., hydrogen_bond, salt_bridge).

evidence

string

Detection confidence level (e.g., explicit, detected, candidate).

entity1 / entity2

string

The names of the interacting entities (as defined in InteractionEntity).

atom_index1 / atom_index2

integer

0-indexed structure atom indices for the interacting atoms.

chain1 / chain2

string

Chain identifiers.

res_id1 / res_id2

integer

Residue sequence numbers.

ins_code1 / ins_code2

string

Insertion codes.

res_name1 / res_name2

string

Residue names (e.g., ALA, LYS).

atom_name1 / atom_name2

string

Atom names (e.g., CA, NZ).

element1 / element2

string

Chemical elements (e.g., C, N, O).

role1 / role2

string

The role of each atom in the interaction (e.g., donor, acceptor, positive, negative, metal).

distance_a

float

The distance between the interacting atoms in Å.

angle_deg

float

The angle of the interaction in degrees (e.g., donor-H-acceptor angle).

vdw_gap_a

float

The Van der Waals gap/overlap in Å.

source

string

The module name or engine source generating the interaction (e.g., geometric_rules).

rule_set

string

The name of the rule set (defaults to default).

rule_version

string

The version of the rule set (defaults to 1.0).

model_id

integer

The model index within the ensemble (1-indexed).

details

dict

Extra metadata (e.g. hydrogen atom index, donor-H and H-acceptor distance).

The pandas DataFrame returned by calling InteractionReport.coordination_centers_dataframe() contains the following columns:

Coordination Center DataFrame Columns#

Column Name

Type

Description

center_id

string

Unique, deterministically-assigned center identifier (e.g., coord_1).

metal_atom_index

integer

0-indexed structure atom index of the coordinating metal.

entity

string

The name of the entity containing the metal.

chain

string

Chain identifier of the metal.

res_id

integer

Residue sequence number of the metal.

ins_code

string

Insertion code.

res_name

string

Residue name of the metal.

atom_name

string

Atom name of the metal.

element

string

Chemical element of the metal.

coordination_number

integer

Number of coordinating donor atoms.

donor_atom_indices

sequence

List of 0-indexed structure atom indices of the coordinating donor atoms.

donor_elements

sequence

List of chemical elements of the donor atoms.

geometry

string

Classified coordination geometry (e.g., tetrahedral, octahedral, linear, trigonal planar, square planar).

geometry_deviation_deg

float

The root-mean-square deviation (RMSD) of pairwise donor-metal-donor angles from the ideal geometry in degrees.

evidence

string

Best evidence level among coordinating donors (e.g., explicit, detected, candidate).

rule_set

string

The name of the rule set.

rule_version

string

The version of the rule set.

model_id

integer

The model index within the ensemble (1-indexed).

Ligand Templates and Atom Ordering#

When performing interaction analysis involving non-polymer ligands, the SDK relies on RDKit for chemical typing (such as determining formal charges, donor/acceptor roles, and hybridization).

Important

The 0-indexed atom order of the RDKit molecule supplied as rdkit_mol must match the 1-to-1 order of the structure atom indices specified in InteractionEntity.atom_indices.

If the atom indices are sorted as [100, 101, 102, 103], then RDKit atom index 0 corresponds to structure atom index 100, RDKit atom index 1 corresponds to structure atom index 101, and so on. Mismatched ordering will result in incorrect interaction typing.

from rdkit import Chem
from neurosnap.structure import InteractionEntity

# Assume ligand atoms are at indices 50 to 55 in the Structure
atom_indices = list(range(50, 56))

# The SMILES string must be constructed so that its atom order
# matches the sequential atom positions in the PDB structure.
rdkit_mol = Chem.MolFromSmiles("CCOCCO")

ligand_entity = InteractionEntity(
    name="ligand_1",
    atom_indices=atom_indices,
    rdkit_mol=rdkit_mol
)

Metal Coordination and Geometry Deviation#

The coordination geometry of metal centers is classified for coordination numbers between 2 and 6. The SDK compares the distribution of pairwise donor-metal-donor angles against ideal geometric templates:

  • CN=2: linear (ideal: 180.0°)

  • CN=3: trigonal planar (ideal: 120.0° x 3)

  • CN=4: tetrahedral (ideal: 109.5° x 6) or square planar (ideal: 90.0° x 4, 180.0° x 2)

  • CN=5: trigonal bipyramidal (ideal: 90.0° x 6, 120.0° x 3, 180.0° x 1) or square pyramidal (ideal: 90.0° x 8, 180.0° x 2)

  • CN=6: octahedral (ideal: 90.0° x 12, 180.0° x 3)

The best-fitting template is determined by minimizing the root-mean-square deviation (RMSD) between the actual sorted angles and the ideal sorted angles. This RMSD value is returned in the geometry_deviation_deg column.

from neurosnap.structure import analyze_interactions

# Retrieve metal coordination reports
report = analyze_interactions(structure, interaction_types=["metal_coordination"])
coord_df = report.coordination_centers_dataframe()
for idx, row in coord_df.iterrows():
    print(f"Metal: {row['element']} | Geometry: {row['geometry']} | Dev: {row['geometry_deviation_deg']:.2f}°")

Explicit Records in PDB Files#

SSBOND and LINK records are read into Structure.bonds with the matching BondType, and written back out on save, so a bond classification survives a round trip:

  • SSBOND maps to BondType.DISULFIDE with bond_order = 1.

  • LINK maps to BondType.METAL_COORDINATION with bond_order = 0 when either endpoint is a metal, and to BondType.COVALENT otherwise.

CONECT records cannot express either category: they carry no bond-type field and cannot represent bond_order = 0. Metal-coordination bonds are therefore written as LINK and omitted from CONECT, so re-reading a saved file does not silently downgrade them to ordinary covalent bonds.

A file may repeat the same LINK pair several times. Because a bond table holds one row per atom pair, those repeats collapse into a single bond.

pLDDT Distribution Summaries#

The SDK provides granular summaries of the predicted Local Distance Difference Test (pLDDT) confidence metric. Calling summarize_plddt automatically detects the input scale ([0, 1] vs [0, 100]) and returns a PLDDTReport with pre-computed summaries.

from neurosnap.structure.confidence import summarize_plddt

# Compute the pLDDT confidence report
report = summarize_plddt(structure, source="b_factor", scale="auto", boundaries=(50, 70, 90))

# The 'distribution' DataFrame contains counts and percentages for each bin
print(report.distribution)

Example distribution output:

         count  percentage
<50          5        5.00
50-70       15       15.00
70-90       30       30.00
>=90        50       50.00

Explicit Limitations#

When using the Neurosnap SDK for interaction and confidence analysis, keep the following limitations in mind:

  1. No Bond Probability: The interaction engine relies on binary geometric and topological thresholds to classify contacts. It does not predict continuous bond probabilities or confidence levels for covalent/non-covalent bonds.

  2. No Binding Affinity: The engine identifies physical contacts and geometric coordination, but does not calculate binding free energies (\(\Delta G\)), dissociation constants (\(K_d\)), or half-maximal inhibitory concentrations (\(IC_{50}\)).

  3. No Automatic Protonation/Tautomer/Oxidation-State Inference: The user is responsible for preparing the input structure (e.g. adding hydrogens, checking protonation and tautomer states). No automatic correction of chemical states is performed.

  4. No QM/MM or Energy Calculations: All calculations are purely geometric and heuristic. No quantum mechanical (QM) or molecular mechanics (MM) force fields are evaluated.

  5. No Job or Download Functionality: The SDK operates entirely on local coordinate files and in-memory structures. It does not interface with remote queues, hosted job schedulers, or external structural databases.

  6. Ligand Chemistry Requires a Template: hydrogen_bond and salt_bridge type ligand donors, acceptors, and formal charges from an aligned RDKit molecule. A ligand without one is left untyped and a warning names it; polymer chemistry is still evaluated, so the analysis proceeds rather than failing.

  7. Hydrogen Bonds Need Hydrogens: Donor-H-acceptor angles cannot be measured without explicit hydrogens. On a structure with none, the rule reports nothing and warns; pass include_candidates=True for distance-only candidates.

Search documentation