Dihedral angles - how to calculate

Andrew Dalke dalke at ks.uiuc.edu
Thu Feb 20 10:42:37 EST 1997


> Can anyone provide me with the procedure or
> point me to a readily intelligible text or other source.

You might want to take a look at psiphi.for from the PDB.
It is at ftp.pdb.bnl.gov:/pub/pdb_software/program_tape/psiphi.for


C                             PROTEIN DATA BANK SOURCE CODE       
C                             AUTHOR. L.ANDREWS,G.WILLIAMS,F.BERNSTEIN
C                             ENTRY DATE.  5/78   SUPPORTED             
C                             LAST REVISION.  9/79                      
C                             PURPOSE. MAIN-CHAIN TORSION ANGLES        
C                             LANGUAGE. FORTRAN IV                      

C     PROTEIN DATA BANK PROGRAM PHIPSI, TO CALCULATE THE MAIN-CHAIN 
C     TORSION ANGLES PHI,PSI AND OMEGA FROM A PROTEIN DATA BANK ENTRY.

However, even though it looks like a well-written Fortran program,
I can't make much out of it, so here's what our code does:

  // get the coordinates of the four atoms
  if(!normal_atom_coord(objIndex[0], comIndex[0], pos1))
    return 0.0;
  if(!normal_atom_coord(objIndex[1], comIndex[1], pos2))
    return 0.0;
  if(!normal_atom_coord(objIndex[2], comIndex[2], pos3))
    return 0.0;
  if(!normal_atom_coord(objIndex[3], comIndex[3], pos4))
    return 0.0;

  // vectors between them
  subtract(r1, pos1, pos2);
  subtract(r2, pos3, pos2);
  subtract(r3, pos2, pos3);
  subtract(r4, pos4, pos3);
  
  // planes' normals
  cross_prod(n1, r1, r2);
  cross_prod(n2, r3, r4);
  
  // angle between them
  return(geomValue = angle(n1, n2));
}

and the funtions used here are defined as:

extern float angle(float *a, float *b) {
  register float amag = sqrtf(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
  register float bmag = sqrtf(b[0] * b[0] + b[1] * b[1] + b[2] * b[2]);
  register float dotprot = a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
  if (amag == 0 || bmag == 0) {
    return 180;
  }
  return (57.2958 * acosf(dotprot / (amag * bmag)));
}


void cross_prod(float *x1, float *x2, float *x3)
{
  x1[0] =  x2[1]*x3[2] - x3[1]*x2[2];
  x1[1] = -x2[0]*x3[2] + x3[0]*x2[2];
  x1[2] =  x2[0]*x3[1] - x3[0]*x2[1];
}

void subtract(float *a, float *b, float *c)
{
 a[0]=b[0]-c[0];
 a[1]=b[1]-c[1];
 a[2]=b[2]-c[2];
}

  So, a Fortran and a C solution.  Hope this helps.

						Andrew
						dalke at ks.uiuc.edu




More information about the Xtal-log mailing list