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 ) |
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, |
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.
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, |
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.
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 ) |
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 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 |
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 );
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, |
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).
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 );
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, |
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.
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 );
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 );