Tutorial:Molecular alignments

From MSL-Libraries
Jump to navigationJump to search

This is an example on how to align whole structures or parts of structures in MSL. This tutorial explains functions in the Transforms object.


Complete source of example_molecular_alignment.cpp


In MSL the program alignMolecules utilizes the type of code in this tutorial to structurally align multiple PDB files, given a set of reference atoms.


To compile

% make bin/example_molecular_alignment

To run the program

Go to the main directory and run the command (note, the location of the exampleFiles subdirectory needs to be provided as an argument)

% bin/example_molecular_alignment exampleFiles

Program description

First you just read two molecules into AtomContainers as seen on the AtomContainer Tutorial

 	string refFile = "example0005.pdb";
	refFile = (string)argv[1] + "/" + refFile;
	cout << "Create an AtomContainer and read the atoms from " << refFile << endl;


	string moveFile = "example0006.pdb";
	moveFile = (string)argv[1] + "/" + moveFile;
	cout << "Create an AtomContainer and read the atoms from " << moveFile << endl;

 

	// read the PDB into a new AtomContainer "refAtoms"
	AtomContainer refAtoms;
	if (!refAtoms.readPdb(refFile)) {
		// error checking, the PDB could not be read
		cerr << endl;
		cerr << "File " << refFile << " cannot be found, please speficy the path of the \"exampleFiles\" directory as an argument" << endl;
		exit(1);
	} else {
	  cout << "Reference PDB has "<<refAtoms.size()<<" atoms."<<endl;
	}

	// read the PDB into a new AtomContainer "moveAtoms"
	AtomContainer moveAtoms;
	if (!moveAtoms.readPdb(moveFile)) {
		// error checking, the PDB could not be read
		cerr << endl;
		cerr << "File " << moveFile << " cannot be found, please speficy the path of the \"exampleFiles\" directory as an argument" << endl;
		exit(1);
	} else {
	  cout << "Move PDB has "<<moveAtoms.size()<<" atoms."<<endl;
	}

Next we check before we move any molecules what the RMSD is, by using the AtomPointerVector::rmsd(AtomPointerVector) function.

	// Get RMSD before alignment
	double preRMSD = refAtoms.getAtomPointers().rmsd(moveAtoms.getAtomPointers());

Create a Transforms object and align the two AtomPointerVectors. Note AtomPointerVectors must contain the same number of atoms and it will try to align the atoms in order.

	// Create a Transforms object (includes functions to do molecular alignments)
	Transforms alignAtoms;

	// Do molecular alignment first atoms are moving, second atoms are the reference
	if (!alignAtoms.rmsdAlignment(moveAtoms.getAtomPointers(),refAtoms.getAtomPointers())){
	  cerr << "ERROR alignment of molecules using all the atoms of reference: "<<refFile<<" and move: "<<moveFile<<" files."<<endl;
	  exit(0);
	}

Finally, get the post-alignment RMSD and print out the results... including the Transformation matrix and translation

	// Get RMSD after alignment
	double postRMSD = refAtoms.getAtomPointers().rmsd(moveAtoms.getAtomPointers());

	// Query Transform object for the rotation and translations required for alignment
	Matrix rotMatrix           = alignAtoms.getLastRotationMatrix();
	CartesianPoint translation = alignAtoms.getLastTranslation();

	// Output RMSD, Rotation Matrix and Translation Vector
	cout << endl << endl;
	fprintf(stdout,"Before alignment RMSD: %8.3f\n",preRMSD);
	fprintf(stdout,"After  alignment RMSD: %8.3f\n",postRMSD);
	cout << endl << endl;

	cout << "Rotation Matix: " <<endl<<rotMatrix << endl;
	cout << "Translation Vector: "<<endl<<translation << endl;



Back to the tutorial page