1
$\begingroup$

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:

enter image description here

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)
    {
    }
}
$\endgroup$
8
  • $\begingroup$ would you share your code with us ? $\endgroup$
    – pippo1980
    Nov 26, 2022 at 17:55
  • $\begingroup$ @pippo1980, its a part of a bigger framework. I am sharing a smaller part of it. Hope that helps. $\endgroup$
    – user366312
    Nov 26, 2022 at 18:11
  • $\begingroup$ unfortunately not, but could help others. Did you try running it on first T of 3NIR.pdb ? $\endgroup$
    – pippo1980
    Nov 26, 2022 at 18:18
  • $\begingroup$ @pippo1980, Yes. My code works now. Previously, I made mistakes with radii values. $\endgroup$
    – user366312
    Nov 26, 2022 at 18:21
  • $\begingroup$ is that above C# ? $\endgroup$
    – pippo1980
    Nov 26, 2022 at 18:32

1 Answer 1

3
$\begingroup$

Your method doesn't work for two possible reasons;

  1. The radius information may be incorrect.
  2. Your molecule requires some minimization. This option helps to optimize distance between atoms.

You can find some information about the minimization at the following links

  1. Wikipedia
  2. Gromacs
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.