CCP4 Coordinate Library Project

Object interface: Coordinate Transformations.

This section presents a collection of different functions for performing different types of coordinate transformations on the coordinate hierarchy, such as fractionalizing/orthogonalizing, symmetry mating and rotation.

Function Purpose
CMMDBManager::ApplyTransform Applying the transformation matrix to all coordinates.
CMMDBManager::Orth2Frac Orthogonal-to-fractional transformation of coordinates.
CMMDBManager::Frac2Orth Fractional-to-orthogonal transformation of coordinates.
CMMDBManager::GenerateSymMates Generating the symmetry mates of the coordinate hierarchy.
CMMDBManager::EulerRotation Euler rotation of coordinates.
CMMDBManager::VectorRotation Rotating coordinates about an arbitrary vector.


void CMMDBManager::ApplyTransform ( 
mat44 &  TMatrix )
PURPOSE
Applying the transformation matrix to all coordinates.
ARGUMENTS
mat44 & TMatrix
The transformation matrix.

DESCRIPTION

The function applies the rotational-translational transformation given by matrix TMatrix, to coordinates of all atoms in the coordinate hierarchy.

The transformation matrix TMatrix contains rotational part in columns 0,1,2, rows 0,1,2 (stands for x,y,z) and translational part in column 3, rows 0,1,2.


Boolean CMMDBManager::Orth2Frac ( 
realtype  xorth, 
realtype yorth,
realtype zorth,
realtype & xfrac,
realtype & yfrac,
realtype & zfrac )
PURPOSE
Orthogonal-to-fractional transformation of coordinates.
ARGUMENTS
realtype xorth
orthogonal X-coordinate

realtype yorth
orthogonal Y-coordinate

realtype zorth
orthogonal Z-coordinate

realtype & xfrac
fractional X-coordinate

realtype & yfrac
fractional Y-coordinate

realtype & zfrac
fractional Z-coordinate

DESCRIPTION

The function calculates fractional coordinates (xfrac,yfrac,zfrac) corresponding to orthogonal coordinates (xorth,yorth,zorth) using crystallographic information (cell dimension data) currently set in the coordinate hierarchy.


RETURN

The function returns True if the fractional coordinates have been successfully calculated. Return of False indicates that cell parameters were not set up. In the latter case, the fractional coordinates are not calculated.


Boolean CMMDBManager::Frac2Orth ( 
realtype  xfrac, 
realtype yfrac,
realtype zfrac,
realtype & xorth,
realtype & yorth,
realtype & zorth )
PURPOSE
Fractional-to-orthogonal transformation of coordinates.
ARGUMENTS
realtype xfrac
fractional X-coordinate

realtype yfrac
fractional Y-coordinate

realtype zfrac
fractional Z-coordinate

realtype & xorth
orthogonal X-coordinate

realtype & yorth
orthogonal Y-coordinate

realtype & zorth
orthogonal Z-coordinate

DESCRIPTION

The function calculates orthogonal coordinates (xorth,yorth,zorth) corresponding to fractional coordinates (xfrac,yfrac,zfrac) using crystallographic information (cell dimension data) currently set in the coordinate hierarchy.


RETURN

The function returns True if the orthogonal coordinates have been successfully calculated. Return of False indicates that cell parameters were not set up. In the latter case, the orthogonal coordinates are not calculated.


int CMMDBManager::GenerateSymMates ( 
PCGenSym   GenSym )
PURPOSE
Generating the symmetry mates of the coordinate hierarchy.
ARGUMENTS
PCGenSym GenSym
The symmetry operations container. It may be set to NULL, in which case the function uses symmetry operations corresponding to the space group currently set in the coordinate hierarchy.

DESCRIPTION

The function generates symmetry mates according to symmetry operations found in GenSym. Results of first symmetry operation (number 0) always replace the existing set of atoms, others are added as additional sets.

The symmetry operations container GenSym contains only the set of symmetry operations and, as an option, the rules for naming the newly generated chains. The function uses the cell geometry information currently set in the coordinate hierarchy.

If GenSym is set to NULL, the function generates all symmetry mates for the unit cell according to the symmetry information currently set in the coordinate hierarchy.

The newly generated chains are added to each model. These chains have many-character chain names, composed as 'x_n', where 'x' is the original chain name and 'n' is a unique number, which coincides with the symmetry operation (order) number; number '_0' (for the very first symmetry operation) is missing so that the original set of chains (after performing the 0th symmetry operation on it) is not renamed. Another side effect of the function is the disorder in atoms' serial numbers. The hierarchy should therefore be cleaned after generating the symmetry mates. An appropriate way to do that could be to issue the following call (see CMMDBManager::PDBCleanup):
   CMMDBManager::PDBCleanup ( PDBCLEAN_CHAIN_STRONG | PDBCLEAN_SERIAL );
    


RETURN

Return Code   Value   Description
GSM_Ok   0   Success
GSM_NoSymOps   1   No symmetry operations found
GSM_NoTransfMatrices   2   No fractionalization/orthogonalization matrices found
GSM_NoCell   3   No cell parameters found


EXAMPLE 1

Generate a unit cell:

CMMDBManager MMDB;
int          RC;

  // read coordinate file
  RC = MMDB.ReadCoorFile ( CoorFileName );
  if (RC) {
    // i/o error handling
    . . . . . . . . . .
    exit(1);
  }

  // if coordinate file does not contain space group or it is
  // incorrect, the application must set one
  if (!MMDB.isSpaceGroup())  {
    // space group name is for demonstration only
    RC = MMDB.SetSpaceGroup ( "P 21 21 21" );
    if (RC!=SYMOP_Ok)   {
      switch (RC)  {
        case SYMOP_NoLibFile :
            printf ( " **** error: can't find symop.lib\n" );
          break;
        case SYMOP_UnknownSpaceGroup :
            printf ( " **** error: attempt to set up unknown space group\n" );
          break;
        case SYMOP_NoSymOps :
            printf ( " **** error: no symmetry operations found\n" );
          break;
        default :
            printf ( " **** error: unknown return code from "
                     "CMMDBManager::SetSpaceGroup()\n" );
      }
      exit(2);
    }
  }

  // if coordinate file does not contain cell parameters or they are
  // incorrect, the application must set them
  if (!MMDB.isCrystInfo())  {
    // numerical values are for demonstration only
    a        = 100.0;
    b        = 100.0;
    c        = 100.0;
    alpha    = 90.0;
    beta     = 90.0;
    gamma    = 90.0;
    OrthCode = 0;
    MMDB.SetCell ( a,b,c,alpha,beta,gamma,OrthCode );
  }

  // it is a good idea to check the completeness of the crystallographic
  // information before generating the symmetry mates. Although the
  // generating function (see below) would return a signal if unit
  // cell cannot be generated.
  RC = MMDB.CrystReady();
  if (RC>0)  {
    // warnings and infos:
    if (RC & CRRDY_NotPrecise)
      printf ( " --- warning: cryst data is not precise\n" );
    if (RC & CRRDY_isTranslation)
      printf ( " --- warning: cryst data contains translation\n" );
    if (RC & CRRDY_NoOrthCode)
      printf ( " --- warning: no orthogonalization code\n" );
  } else  {
    // fatal errors:
    switch (RC)  {
      case CRRDY_Complete : break;   // it's Ok
      case CRRDY_NoTransfMatrices :
           printf ( " *** error : transformation matrices were not "
                    "calculated\n" );
         break;
      case CRRDY_Unchecked :
           printf ( " *** error : fail to check cryst data\n" );
         break;
      case CRRDY_Ambiguous :
           printf ( " *** error : cryst data is ambiguous\n" );
         break;
      case CRRDY_NoCell    :
           printf ( " *** error : missing cryst data\n" );
         break;
      default :
           printf ( " *** error : unknown return code from "
                    "CMMDBManager::CrystReady()\n" );
    }
    exit(3);
  }

  // now generate the unit cell:
  RC = MMDB.GenerateSymMates ( NULL );
  switch (RC)  {
    case GSM_Ok       : break;  // it's Ok
    case GSM_NoSymOps : printf ( " *** error: no symmetry operations "
                                 "found\n" );
                     exit(4);
    case GSM_NoTransfMatrices :
                        printf ( " *** error: Fractionalization/"
                                 "Orthogonalization is not defined\n" );
                     exit(4);
    case GSM_NoCell   : printf ( " *** error: No cell parameters were "
                                 "set up\n" );
                     exit(4);
    default : printf ( " *** error: unknown return from "
                       "CMMDBManager::GenerateSymMates()\n" );
                     exit(4);
  }

  // make 1-character chain names and recalculate the atom serial
  // numbers
  MMDB.PDBCleanup ( PDBCLEAN_CHAIN_STRONG | PDBCLEAN_SERIAL );


EXAMPLE 2

Generate specific symmetry mates:

CMMDBManager MMDB;
int          RC;
CGenSym      GenSym;

  // read coordinate file
  RC = MMDB.ReadCoorFile ( CoorFileName );
  if (RC) {
    // i/o error handling
    . . . . . . . . . .
    exit(1);
  }

  // if coordinate file does not contain cell parameters or they are
  // incorrect, the application must set them
  if (!MMDB.isCrystInfo())  {
    // numerical values are for demonstration only
    a        = 100.0;
    b        = 100.0;
    c        = 100.0;
    alpha    = 90.0;
    beta     = 90.0;
    gamma    = 90.0;
    OrthCode = 0;
    MMDB.SetCell ( a,b,c,alpha,beta,gamma,OrthCode );
  }

  // ===================================================================
  // unlike example #1, we do not perform a check for crystallographic
  // information here. This checking is done by the
  // CMMDBmanager::GenerateSymMates() function.
  // ===================================================================

  //  Fill in the CGenSym class by symmetry operations.
  //  First operation - the identity. It does not have to be so,
  // however it is convenient if identity should be there
  GenSym.AddSymOp ( "X,Y,Z" );  // first operation don't rename chains

  //  Set up 2nd operation (example only)
  GenSym.AddSymOp    ( "X-1/2,-Y+1/2,Z" );
  //  2nd operation will rename chains. We can specify the renaming
  //  rules here instead of calling CMMDBManager::PDBCleanup() for
  //  making 1-character chain IDs after generating new chains
  GenSym.AddRenChain ( 1,"A","C" );  //  rename A to C
  GenSym.AddRenChain ( 1,"B","D" );  //  rename B to D

  //  Set up 3rd operation
  GenSym.AddSymOp    ( "-X,-Y,Z+1" );
  GenSym.AddRenChain ( 1,"A","E" );  //  rename A to E
  GenSym.AddRenChain ( 1,"B","F" );  //  rename B to F

  // now generate the symmetry mates:
  RC = MMDB.GenerateSymMates ( &GenSym );
  switch (RC)  {
    case GSM_Ok       : break;  // it's Ok
    case GSM_NoSymOps : printf ( " *** error: no symmetry operations "
                                 "found\n" );
                     break;
    case GSM_NoTransfMatrices :
                        printf ( " *** error: Fractionalization/"
                                 "Orthogonalization is not defined\n" );
                     break;
    case GSM_NoCell   : printf ( " *** error: No cell parameters were "
                                 "set up\n" );
                     break;
    default : printf ( " *** error: unknown return from "
                       "CMMDBManager::GenerateSymMates()\n" );
  }

  // ====================================================================
  // unlike example #1, we do not call CMMDBManager::PDBCleanup() here.
  // If GenSym contains renaming rules for all chains and all operations,
  // the newly generated chains already have proper IDs. In this example,
  // if the original file had chains A and B only, we get chains:
  //   A and B  - former A and B transformed as X,Y,Z (identity)
  //   C and D  - former A and B transformed as X-1/2,-Y+1/2,Z
  //   E and F  - former A and B transformed as -X,-Y,Z+1
  // ====================================================================


void CMMDBManager::EulerRotation ( 
PPCAtom  A, 
int nA,
realtype alpha,
realtype beta,
realtype gamma,
realtype x0,
realtype y0,
realtype z0 )
PURPOSE
Euler rotation of coordinates.
ARGUMENTS
PPCAtom A
Array of atoms to be rotated. This array may conveniently come from selection functions.

int nA
Number of atoms in array A. The array is indexed as 0..nA-1 .

realtype alpha
Euler angle of alpha-rotation (first rotation about original Z-axis), in radians.

realtype beta
Euler angle of beta-rotation (second rotation about new Y-axis), in radians.

realtype gamma
Euler angle of gamma-rotation (third rotation about newest Z-axis), in radians.

realtype x0
X-coordinate of the rotation center (orthogonal).

realtype y0
Y-coordinate of the rotation center (orthogonal).

realtype z0
Z-coordinate of the rotation center (orthogonal).

DESCRIPTION

The function performs the Euler rotation of atoms given in array A. First the atoms are rotated about original Z-axis through angle alpha, then about new Y-axis through angle beta, and finally about the newest Z-axis through angle gamma. The rotation center is given by point (x0,y0,z0).


EXAMPLE 1

Rotate all coordinate hierarchy through Euler angles of 90,180,45 degrees about the coordinate center:

CMMDBManager  MMDB;
PPCAtom       A;
int           nA;

  //  reading the coordinate file
  . . . . . . . . . . . .

  MMDB.GetAtomTable  ( A,nA );
  MMDB.EulerRotation ( A,nA, Pi/2.0,Pi,Pi/4.0, 0.0,0.0,0.0 );


EXAMPLE 2

Rotate chain A through Euler angles of -30,90,60 degrees about its center of mass:

CMMDBManager  MMDB;
PPCAtom       A;
int           nA,selHnd;
realtype      xmc,ymc,zmc;

  //  reading the coordinate file
  . . . . . . . . . . . .

  selHnd = MMDB.NewSelection();
  MMDB.Select      ( selHnd,STYPE_ATOM,0,"A",ANY_RES,"*",ANY_RES,"*",
                     "*","*","*","*",SKEY_NEW );
  MMDB.GetSelIndex ( selHnd,A,nA );

  if (nA>0)  {
    MMDB.GetMassCenter ( A,nA, xmc,ymc,zmc );
    MMDB.EulerRotation ( A,nA, -Pi/6.0,Pi/2.0,Pi/3.0, xmc,ymc,zmc );
  }

  MMDB.DeleteSelection ( selHnd );


int CMMDBManager::VectorRotation ( 
PPCAtom  A, 
int nA,
realtype alpha,
realtype vx,
realtype vy,
realtype vz,
realtype x0,
realtype y0,
realtype z0 )
PURPOSE
Rotating coordinates about an arbitrary vector.
ARGUMENTS
PPCAtom A
Array of atoms to be rotated. This array may conveniently come from selection functions.

int nA
Number of atoms in array A. The array is indexed as 0..nA-1 .

realtype alpha
rotation angle, in radians.

realtype vx
X-component of the rotation vector.

realtype vy
Y-component of the rotation vector.

realtype vz
Z-component of the rotation vector.

realtype x0
X-origin of the rotation vector.

realtype y0
Y-origin of the rotation vector.

realtype z0
Z-origin of the rotation vector.

DESCRIPTION

The function performs rotation of atoms given in array A about vector (vx,vy,vz) originating in point (x0,y0,z0). The rotation is done clockwise in the direction of the vector.

The vector {(x0,y0,z0) -> (x0+vx,y0+vy,z0+vz)} specifies only the rotation axis, thus it may be of any non-zero length.


EXAMPLE 1

Rotate all coordinate hierarchy through angle of 90 degrees about axis forming angle of 45 degrees with X-axis in XY-plane:

CMMDBManager  MMDB;
PPCAtom       A;
int           nA;

  //  reading the coordinate file
  . . . . . . . . . . . .

  MMDB.GetAtomTable   ( A,nA );
  MMDB.VectorRotation ( A,nA, Pi/2.0, 1.0,1.0,0.0, 0.0,0.0,0.0 );


EXAMPLE 2

Rotate chain A through angle of 90 degrees about vector connecting atoms A/33/CA[C] and A/34/CA[C]:

CMMDBManager  MMDB;
PPCAtom       A;
int           nA,selHnd;
PCAtom        A1,A2;
realtype      vx,vy,vz;

  //  reading the coordinate file
  . . . . . . . . . . . .

  A1 = MMDB.GetAtom ( 1,"A",33,"","CA","C","" );
  if (!A1)  {
    printf ( " **** error: atom /1/A/33/CA[C] does not exist\n" );
    exit ( 1 );
  }
  A2 = MMDB.GetAtom ( "/1/A/34/CA[C]" );
  if (!A2)  {
    printf ( " **** error: atom /1/A/34/CA[C] does not exist\n" );
    exit ( 1 );
  }

  selHnd = MMDB.NewSelection();
  MMDB.Select      ( selHnd,STYPE_ATOM,0,"A",ANY_RES,"*",ANY_RES,"*",
                     "*","*","*","*",SKEY_NEW );
  MMDB.GetSelIndex ( selHnd,A,nA );

  if (nA>0)  {
    vx = A2->x - A1->x;
    vy = A2->y - A1->y;
    vz = A2->z - A1->z;
    MMDB.VectorRotation ( A,nA, Pi/2.0, vx,vy,vz, A1->x,A1->y,A1->z );
  }

  MMDB.DeleteSelection ( selHnd );



Back to index