The direct geometric estimation of solvent accessible surface area for example by the Shrake-Rupley algorithm adds to the computational burden of docking and other applications. We would like to treat each amino acid as a rigid body and precalculate the solvent accessible envelope. Then the shape of the protein can be proxied by these envelopes and their intersections reducing computational burden for docking. This approach could help produce geometrically smoother envelopes than the rolling ball of 1.4 Angstroms that is commonly used.

The geometric components for an envelope are hemisphere for an end, cylindrical tubes for bonds, and intersections can be smoothened out. The radius is 1.4 Angstroms larger than the atomic radii.

Basic spherical intersection code to determine the envelope for an individual amino acid is here:

from prody import * import numpy as np prot1 = '1FGN' p = parsePDB(prot1) res = p.getResnames() idx = p.getResindices() C = p.getCoords() E = p.getElements() i0 = 0 a1 = [] a1e = [] for j in range(len(C)): if idx[j] == i0: a1.append(C[j]) a1e.append(E[j]) radC = 0.70 radN = 0.65 radH = 0.25 radO = 0.60 N = 200 mesh = np.zeros((N,N,N)) center = np.array([N/2,N/2,N/2]) delta = 0.1 # angstroms # translate the initial N to the center v1 = a1[0] def distance(a,b): return np.linalg.norm(a-b) def spherical_boundary( center_coord, radius, mesh ): rN = int(radius/delta) for i in range(center_coord[0]-rN,center_coord[0]+rN): for j in range(center_coord[1]-rN,center_coord[1]+rN): for k in range(center_coord[2]-rN,center_coord[2]+rN): d = distance(np.array([i,j,k]),center_coord)*delta if d < radius-delta: mesh[i,j,k] = 0.0 if d >= radius-delta and d <= radius+delta: mesh[i,j,k]=1.0 if d > radius+delta: mesh[i,j,k] = 0.0 for i in range(len(a1)): acv = a1[i] - v1 + center*delta atom_center = np.array([int(acv[0]/delta),int(acv[1]/delta),int(acv[2]/delta)]) atom_rad = 0.5 if a1e[i] == 'C': atom_rad = 0.7 if a1e[i] == 'H': atom_rad = 0.25 if a1e[i] == 'N': atom_rad = 0.65 if a1e[i] == 'O': atom_rad = 0.60 spherical_boundary(atom_center, atom_rad + 1.4, mesh) # At this point the mesh should contain the surface of the amino acid