Let us consider the first seven atoms of the protein 1CRN.pdb
:
ATOM 1 N THR A 1 17.047 14.099 3.625 1.00 13.79 N
ATOM 2 CA THR A 1 16.967 12.784 4.338 1.00 10.80 C
ATOM 3 C THR A 1 15.685 12.755 5.133 1.00 9.19 C
ATOM 4 O THR A 1 15.268 13.825 5.594 1.00 9.85 O
ATOM 5 CB THR A 1 18.170 12.703 5.337 1.00 13.02 C
ATOM 6 OG1 THR A 1 19.334 12.829 4.463 1.00 15.06 O
ATOM 7 CG2 THR A 1 18.150 11.546 6.304 1.00 14.23 C
This represents an amino acid called Threonine.
The general bond diagram for Threonine is as follows:
So, it has at least six bonds (I am actually not sure!) which are also evident from the seven ATOM
lines.
Each atom has its radius. In general, if the distance between two atoms is less than the sum of the radii, there is a bond between these two atoms.
Based on the above information, I tried to identify the bond information, and I could detect only two:
atom1 atom2 distance atm1 Radi atom2 Radi sum radi is bond?
N CA 1.50 0.65 0.70 1.35 False
N C 2.44 0.65 0.70 1.35 False
N O 2.67 0.65 0.60 1.25 False
N CB 2.48 0.65 0.70 1.35 False
N OG1 2.75 0.65 0.60 1.25 False
N CG2 3.86 0.65 0.60 1.25 False
CA N 1.50 0.70 0.65 1.35 False
CA C 1.51 0.70 0.70 1.40 False
CA O 2.36 0.70 0.60 1.30 False
CA CB 1.57 0.70 0.70 1.40 False
CA OG1 2.37 0.70 0.60 1.30 False
CA CG2 2.61 0.70 0.60 1.30 False
C N 2.44 0.70 0.65 1.35 False
C CA 1.51 0.70 0.70 1.40 False
C O 1.24 0.70 0.60 1.30 True
C CB 2.49 0.70 0.70 1.40 False
C OG1 3.71 0.70 0.60 1.30 False
C CG2 2.98 0.70 0.60 1.30 False
O N 2.67 0.60 0.65 1.25 False
O CA 2.36 0.60 0.70 1.30 False
O C 1.24 0.60 0.70 1.30 True
O CB 3.12 0.60 0.70 1.30 False
O OG1 4.34 0.60 0.60 1.20 False
O CG2 3.74 0.60 0.60 1.20 False
CB N 2.48 0.70 0.65 1.35 False
CB CA 1.57 0.70 0.70 1.40 False
CB C 2.49 0.70 0.70 1.40 False
CB O 3.12 0.70 0.60 1.30 False
CB OG1 1.46 0.70 0.60 1.30 False
CB CG2 1.51 0.70 0.60 1.30 False
OG1 N 2.75 0.60 0.65 1.25 False
OG1 CA 2.37 0.60 0.70 1.30 False
OG1 C 3.71 0.60 0.70 1.30 False
OG1 O 4.34 0.60 0.60 1.20 False
OG1 CB 1.46 0.60 0.70 1.30 False
OG1 CG2 2.54 0.60 0.60 1.20 False
CG2 N 3.86 0.60 0.65 1.25 False
CG2 CA 2.61 0.60 0.70 1.30 False
CG2 C 2.98 0.60 0.70 1.30 False
CG2 O 3.74 0.60 0.60 1.20 False
CG2 CB 1.51 0.60 0.70 1.30 False
CG2 OG1 2.54 0.60 0.60 1.20 False
2
Done!
How can I detect all bonds?
EDIT: As per pippo1980's request:
public class ADTResidue: Dictionary<int, ADTAtom>, IEquatable<ADTResidue>
{
public string ProteinName { get; set; }
public string ChainName { get; set; }
public int ResidueNo { get; set; }
public Point3d Coordinate { get; private set; }
public string Code { get; set; }
public string Full { get; set; }
public Color ColorRGB { get; set; }
public ADTResidue(string code, string full, Color colorRgb)
{
Coordinate = new Point3d();
Code = code;
Full = full;
ColorRGB = colorRgb;
}
private readonly Dictionary<int, CovalentBond> BondDictionary;
public List<CovalentBond> GetBonds()
{
return new List<CovalentBond>(BondDictionary.Values);
}
public ADTResidue()
{
BondDictionary = new Dictionary<int, CovalentBond>();
}
public void CalculateBonds()
{
foreach (ADTAtom atom1 in this.Values)
{
foreach (ADTAtom atom2 in this.Values)
{
if (atom2.Radius <= 0)
{
throw new Exception("zero radius in " + atom2.Name);
}
if (atom1 != atom2)
{
double distance = Point3d.Distance(atom1.Coordinate, atom2.Coordinate);
bool exists = ABond.IsBondExists(atom1.Coordinate, atom2.Coordinate, atom1.Radius, atom2.Radius);
if (exists)
{
int hashCode = atom1.GetHashCode(atom2);
if (!BondDictionary.ContainsKey(hashCode))
{
BondDictionary.Add(hashCode, new CovalentBond(atom1, atom2));
}
}
}
}
}
int count = BondDictionary.Count;
Console.WriteLine(count);
}
#region equality comparison
// IEquatable<> implementation...
#endregion
}
public abstract class ABond: Pair<ADTAtom, ADTAtom>
{
public ABond():base()
{
}
public ABond(ADTAtom first, ADTAtom second) : base(first, second)
{
}
public static bool IsBondExists(Point3d first, Point3d second, double radius1, double radius2)
{
double distance = Point3d.Distance(first, second);
return (distance <= (radius1 + radius2));
}
}
public class CovalentBond : ABond
{
public CovalentBond():base()
{
}
public CovalentBond(ADTAtom first, ADTAtom second) : base(first, second)
{
}
}