Drawing a Ligand-Protein Complex Surface¶
The previous chapter demonstrates how to draw and customize 2D
molecule surfaces.
Grapheme TK also provides a method that depicts a ligand-protein
complex in which the arcs of the 2D surface of the molecule are
annotated based on the distance between the accessible
surfaces of the ligand and the surrounding protein
(OEMakeAccessibleSurface
).
Based on this calculation, the atoms of the ligand are
divided into four categories which are then inherited by the
corresponding arcs when the 2D molecule surface of the ligand is
drawn.
These four types are the following:
Solvent (OEDefaultSolventArcFxn)
A surface arc is depicted using the solvent style if the corresponding atom is accessible to a solvent. (See Figure: Example of the ‘solvent’ arc style)
Cavity (OEDefaultCavityArcFxn)
A surface arc is depicted using the cavity style if in the region of the corresponding atom, a cavity is detected between the ligand and the receptor molecule surfaces. The cavity is large enough to allow expanding the ligand in this region without bumping into the receptor. (See Figure: Example of the cavity arc style)
Void (OEDefaultVoidArcFxn)
A surface arc is depicted using the void style, if in the region of the corresponding atom a small interstice is detected between the ligand and the receptor molecule surfaces. (See Figure: OEDefaultBuriedArcFxn)
Buried (OEDefaultBuriedArcFxn)
A surface arc is depicted using the buried style, if in the region of the corresponding atom the ligand is tightly fit to the receptor. (See Figure: Example of the buried arc style)
Note
Even though, Spicoli TK is used to generate the accessible surfaces of
the ligand and the receptor, no Spicoli TK license is required to call
the OEAddComplexSurfaceArcs
function.
The following Listing 1
example show how
to display the surface of the ligand-protein complex.
After importing the ligand and the receptor structures, the
OEAddComplexSurfaceArcs
function is called to
generate the accessible molecule surfaces (using Spicoli TK) and assign
the surface drawing styles (solvent, buried, void, or cavity)
for the atoms of the ligand.
These styles are the used to draw the arcs of the molecule surface
when the OEDraw2DSurface
function is invoked.
The OEGetMoleculeSurfaceScale
function is used
to reduce the scaling of the molecule in order to be able to fit
both the molecule diagram and the molecule surface into the image.
Listing 1: Example of complex surface drawing
public class DrawComplexSurface
{
public static OEGraphMol ImportMolecule (String filename)
{
oemolistream ifs = new oemolistream();
OEGraphMol mol = new OEGraphMol();
if (!ifs.open(filename))
{
OEChem.OEThrow.Fatal("Unable to open " + filename + " for reading");
}
if (!OEChem.OEReadMolecule(ifs, mol))
{
OEChem.OEThrow.Fatal("Unable to read molecule in " + filename);
}
OEChem.OEAssignBondiVdWRadii(mol);
OEChem.OESuppressHydrogens(mol);
return mol;
}
public static int Main(String[] args)
{
if (args.Length != 2)
{
OEChem.OEThrow.Usage("DrawComplexSurface <receptor> <ligand>");
}
OEGraphMol receptor = ImportMolecule(args[0]);
OEGraphMol ligand = ImportMolecule(args[1]);
uint width = 450;
uint height = 350;
OEGrapheme.OEAddComplexSurfaceArcs(ligand, receptor);
OEGrapheme.OEPrepareDepictionFrom3D(ligand);
OE2DMolDisplayOptions opts = new OE2DMolDisplayOptions(width, height, OEScale.AutoScale);
opts.SetScale(OEGrapheme.OEGetMoleculeSurfaceScale(ligand, opts));
OE2DMolDisplay disp = new OE2DMolDisplay(ligand, opts);
OEGrapheme.OEDraw2DSurface(disp);
OEDepict.OERenderMolecule("DrawComplexSurface.png", disp);
return 0;
}
}
The following snapshot (Figure: Dihydrofolate reductase)
displays the ligand of the 2w3a PDB complex in VIDA
with the accessible surface of the protein.
The image shown in the Figure: The Grapheme representation of the 2w3a complex
is created by Listing 1
code for the same
ligand-protein complex.
User-defined solvent and buried surface drawing styles can be
implemented by deriving from the
OESurfaceArcFxnBase base class.
Similarly, user-defined cavity and void surface drawing styles can be
implemented by deriving from the
OEComplexSurfaceArcFxnBase base class.
This later abstract class also stores the relative distance calculated
between the ligand and the receptor.
The following code snippet shows how to use this depth to emphasize
the volume of the cavity by adjusting the size of the spikes when
drawing the surface arcs using the OEDrawSunSurfaceArc
function.
private static void DrawSurfaceArc(OEImageBase image, double depth, OESurfaceArc arc, OEPen pen)
{
double edgeAngle = 5.0;
double patternAngle = 5.0;
double minPatternWidthRatio = 0.05;
double maxPatternWidthRatio = 0.10 * depth;
uint patternDirection = OEPatternDirection.Outside;
OEGrapheme.OEDrawSunSurfaceArc(image, arc.GetCenter(), arc.GetBgnAngle(), arc.GetEndAngle(),
arc.GetRadius(), pen, edgeAngle,
patternDirection, patternAngle,
minPatternWidthRatio, maxPatternWidthRatio);
}
private class SolventArcFxn : OESurfaceArcFxnBase
{
public override bool Call(OEImageBase image, OESurfaceArc arc)
{
OEPen pen = new OEPen(OEChem.OELightGrey, OEChem.OELightGrey);
pen.SetLineWidth(0.5);
OEGrapheme.OEDrawDefaultSurfaceArc(image, arc.GetCenter(), arc.GetBgnAngle(),
arc.GetEndAngle(), arc.GetRadius(), pen);
return true;
}
public override OESurfaceArcFxnBase CreateCopy()
{
SolventArcFxn copy = new SolventArcFxn();
copy.ReleaseOwnership();
return copy;
}
}
private class BuriedArcFxn : OESurfaceArcFxnBase
{
public override bool Call(OEImageBase image, OESurfaceArc arc)
{
OEPen pen = new OEPen(OEChem.OEGrey, OEChem.OEGrey);
pen.SetLineWidth(2.0);
OEGrapheme.OEDrawDefaultSurfaceArc(image, arc.GetCenter(), arc.GetBgnAngle(),
arc.GetEndAngle(), arc.GetRadius(), pen);
return true;
}
public override OESurfaceArcFxnBase CreateCopy()
{
BuriedArcFxn copy = new BuriedArcFxn();
copy.ReleaseOwnership();
return copy;
}
}
private class CavityArcFxn : OEComplexSurfaceArcFxnBase
{
public CavityArcFxn() {}
public CavityArcFxn(CavityArcFxn rhs) : base(rhs) {}
public override bool Call(OEImageBase image, OESurfaceArc arc)
{
OEPen pen = new OEPen(OEChem.OEBlack, OEChem.OEBlack);
pen.SetLineWidth(2.0);
DrawSurfaceArc(image, GetDepth(), arc, pen);
return true;
}
public override OEComplexSurfaceArcFxnBase CreateComplexCopy()
{
CavityArcFxn copy = new CavityArcFxn(this);
copy.ReleaseOwnership();
return copy;
}
public override OESurfaceArcFxnBase CreateCopy()
{
CavityArcFxn copy = new CavityArcFxn(this);
copy.ReleaseOwnership();
return copy;
}
}
private class VoidArcFxn : OEComplexSurfaceArcFxnBase
{
public VoidArcFxn() {}
public VoidArcFxn(VoidArcFxn rhs) : base(rhs) {}
public override bool Call(OEImageBase image, OESurfaceArc arc)
{
OEPen pen = new OEPen(OEChem.OEDarkGrey, OEChem.OEDarkGrey);
pen.SetLineWidth(2.0);
DrawSurfaceArc(image, GetDepth(), arc, pen);
return true;
}
public override OEComplexSurfaceArcFxnBase CreateComplexCopy()
{
VoidArcFxn copy = new VoidArcFxn(this);
copy.ReleaseOwnership();
return copy;
}
public override OESurfaceArcFxnBase CreateCopy()
{
VoidArcFxn copy = new VoidArcFxn(this);
copy.ReleaseOwnership();
return copy;
}
}
These arc drawing predicates then can be used to draw the surface of
the ligand-protein complex when calling the
OEAddComplexSurfaceArcs
function.
The image created is shown in
Figure: Example of user-defined surface drawing.
SolventArcFxn sfxn = new SolventArcFxn();
BuriedArcFxn bfxn = new BuriedArcFxn();
CavityArcFxn cfxn = new CavityArcFxn();
VoidArcFxn vfxn = new VoidArcFxn();
OEGrapheme.OEAddComplexSurfaceArcsSpecial(ligand, receptor, sfxn, bfxn, cfxn, vfxn);
See also
Surface Generation chapter in the Spicoli TK manual