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  Orthogonaltofractional transformation of coordinates.

CMMDBManager::Frac2Orth  Fractionaltoorthogonal 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 rotationaltranslational 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 manycharacter 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 1character 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 ( "X1/2,Y+1/2,Z" ); // 2nd operation will rename chains. We can specify the renaming // rules here instead of calling CMMDBManager::PDBCleanup() for // making 1character 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 X1/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 Zaxis through angle alpha, then about new Yaxis through angle beta, and finally about the newest Zaxis 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 nonzero length.Rotate all coordinate hierarchy through angle of 90 degrees about axis forming angle of 45 degrees with Xaxis in XYplane:
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 );