Algorithm & Calculation Logic

1. Algorithm Overview

HBAT uses a geometric approach to identify hydrogen bonds by analyzing distance and angular criteria between donor-hydrogen-acceptor triplets. The main calculation is performed in the _check_hydrogen_bond() method in hbat/core/analysis.py.

2. Core Calculation Steps

Step 1: Donor-Acceptor Identification

  • Donors: Heavy atoms (N, O, S) bonded to hydrogen atoms (_get_hydrogen_bond_donors())

  • Acceptors: Electronegative atoms (N, O, S, F, Cl) (_get_hydrogen_bond_acceptors())

Step 2: Distance Criteria

Two distance checks are performed:

  1. H…A Distance: Hydrogen to acceptor distance

    • Cutoff: 3.5 Å (default from AnalysisDefaults.HB_DISTANCE_CUTOFF)

    • Calculated: Using 3D Euclidean distance via Vec3D.distance_to()

  2. D…A Distance: Donor to acceptor distance

    • Cutoff: 4.0 Å (default from AnalysisDefaults.HB_DA_DISTANCE)

    • Purpose: Ensures realistic hydrogen bond geometry

Step 3: Angular Criteria

  • Angle: D-H…A angle using angle_between_vectors() from hbat/core/vector.py

  • Cutoff: 120° minimum (default from AnalysisDefaults.HB_ANGLE_CUTOFF)

  • Calculation: Uses vector dot product formula: cos(θ) = (BA·BC)/(|BA||BC|)

3. Geometric Validation Process

def _check_hydrogen_bond(donor, hydrogen, acceptor):
    # Distance validation
    h_a_distance = hydrogen.coords.distance_to(acceptor.coords)
    if h_a_distance > 3.5:  # Distance cutoff
        return None

    d_a_distance = donor.coords.distance_to(acceptor.coords)
    if d_a_distance > 4.0:  # Donor-acceptor cutoff
        return None

    # Angular validation
    angle = angle_between_vectors(donor.coords, hydrogen.coords, acceptor.coords)
    if math.degrees(angle) < 120.0:  # Angle cutoff
        return None

    # Bond classification and creation
    return HydrogenBond(...)

4. Key Parameters and Defaults

From hbat/constants.py:

Parameter

Default Value

Description

HB_DISTANCE_CUTOFF

3.5 Å

Maximum H…A distance

HB_ANGLE_CUTOFF

120.0°

Minimum D-H…A angle

HB_DA_DISTANCE

4.0 Å

Maximum D…A distance

COVALENT_CUTOFF_FACTOR

1.2

Bond detection multiplier

5. Covalent Bond Detection

Hydrogen-donor bonds are identified using:

  • Covalent radii from AtomicData.COVALENT_RADII

  • Distance formula: distance (r1 + r2) × 1.2

  • Example: H-N bond = (0.31 + 0.71) × 1.2 = 1.22 Å maximum

6. Vector Mathematics

The Vec3D class (hbat/core/vector.py) provides:

  • 3D coordinates: Vec3D(x, y, z)

  • Distance calculation: √[(x₂-x₁)² + (y₂-y₁)² + (z₂-z₁)²]

  • Angle calculation: arccos(dot_product / (mag1 × mag2))

7. Analysis Flow

  1. Parse PDB file → Extract atomic coordinates

  2. Identify donors → Find N/O/S atoms bonded to H

  3. Identify acceptors → Find N/O/S/F/Cl atoms

  4. Distance screening → Apply H…A and D…A cutoffs

  5. Angular validation → Check D-H…A geometry

  6. Bond classification → Determine bond type (e.g., “N-H…O”)

8. Output Structure

Each detected hydrogen bond is stored as a HydrogenBond dataclass containing:

  • Donor, hydrogen, and acceptor atoms

  • H…A distance and D-H…A angle

  • Bond type classification

  • Residue identifiers

9. Additional Features

Halogen Bonds

HBAT also detects halogen bonds (X-bonds) using similar geometric criteria:

  • Distance: X…A ≤ 4.0 Å

  • Angle: C-X…A ≥ 120°

  • Halogens: F, Cl, Br, I

π Interactions

X-H…π interactions are detected using the aromatic ring center as a pseudo-acceptor:

Aromatic Ring Center Calculation (_calculate_aromatic_center())

The center of aromatic rings is calculated as the geometric centroid of specific ring atoms:

Phenylalanine (PHE): - Ring atoms: CG, CD1, CD2, CE1, CE2, CZ (6-membered benzene ring) - Forms a planar hexagonal structure

Tyrosine (TYR): - Ring atoms: CG, CD1, CD2, CE1, CE2, CZ (6-membered benzene ring) - Same as PHE but with hydroxyl group at CZ

Tryptophan (TRP): - Ring atoms: CG, CD1, CD2, NE1, CE2, CE3, CZ2, CZ3, CH2 (9-atom indole system) - Includes both pyrrole and benzene rings

Histidine (HIS): - Ring atoms: CG, ND1, CD2, CE1, NE2 (5-membered imidazole ring) - Contains two nitrogen atoms in the ring

Centroid Calculation Process

# For each aromatic residue:
center = Vec3D(0, 0, 0)
for atom_coord in ring_atoms_coords:
    center = center + atom_coord
center = center / len(ring_atoms_coords)  # Average position

π Interaction Geometry Validation (_check_pi_interaction())

Once the aromatic center is calculated:

  1. Distance Check: H…π center distance

    • Cutoff: ≤ 4.5 Å (from AnalysisDefaults.PI_DISTANCE_CUTOFF)

    • Calculation: 3D Euclidean distance from hydrogen to ring centroid

  2. Angular Check: D-H…π angle

    • Cutoff: ≥ 90° (from AnalysisDefaults.PI_ANGLE_CUTOFF)

    • Calculation: Angle between donor-hydrogen vector and hydrogen-π_center vector

    • Uses same angle_between_vectors() function as regular hydrogen bonds

Geometric Interpretation

  • The aromatic ring center acts as a “virtual acceptor” representing the π-electron cloud

  • Distance measures how close the hydrogen approaches the aromatic system

  • Angle ensures the hydrogen is positioned to interact with the π-electron density above/below the ring plane

Cooperativity Chains

HBAT identifies cooperative interaction chains where molecular interactions are linked through shared atoms. This occurs when an acceptor atom in one interaction simultaneously acts as a donor in another interaction.

Chain Detection Algorithm (_find_cooperativity_chains())

Step 1: Interaction Collection - Combines all detected interactions: hydrogen bonds, halogen bonds, and π interactions - Requires minimum of 2 interactions to form chains

Step 2: Atom-to-Interaction Mapping Creates two lookup dictionaries:

  • donor_to_interactions: Maps each donor atom to interactions where it participates

  • acceptor_to_interactions: Maps each acceptor atom to interactions where it participates

Atom keys are tuples: (chain_id, residue_sequence, atom_name)

Step 3: Chain Building Process (_build_cooperativity_chain_unified()) Starting from each unvisited interaction:

  1. Initialize: Begin with starting interaction in chain

  2. Follow Forward: Look for next interaction where current acceptor acts as donor

  3. Validation: Ensure same atom serves dual role (acceptor → donor)

  4. Iteration: Continue until no more connections found

  5. Termination: π interactions cannot chain further as acceptors (no single acceptor atom)

Chain Building Logic

# Simplified chain building process:
chain = [start_interaction]
current_interaction = start_interaction

while True:
    current_acceptor = current_interaction.get_acceptor_atom()
    if not current_acceptor:
        break  # No acceptor atom (π interactions)

    # Find interaction where this acceptor acts as donor
    acceptor_key = (acceptor.chain_id, acceptor.res_seq, acceptor.name)

    next_interaction = None
    for candidate in donor_to_interactions[acceptor_key]:
        candidate_donor = candidate.get_donor_atom()
        if candidate_donor matches current_acceptor:
            next_interaction = candidate
            break

    if next_interaction is None:
        break  # Chain ends

    chain.append(next_interaction)
    current_interaction = next_interaction

Cooperativity Examples

Example 1: Sequential H-bonds

Residue A (Donor) --H-bond--> Residue B (Acceptor/Donor) --H-bond--> Residue C (Acceptor)

Example 2: Mixed interactions

Residue A (N-H) --H-bond--> Residue B (O) --X-bond--> Residue C (halogen)