[Biojava-l] 3d structure rotation code

Andreas Prlic ap3 at sanger.ac.uk
Mon Dec 5 09:36:00 EST 2005


Hi!

Regarding the question posted by Tamas for creating artificial 
side-chains for amino acids last week:

To superimpose two (or more) residues/atoms, one needs to do a singular 
value decomposition, which
gives the  required rotation matrix and shift vector.  The recent 
biojava 1.4 release could not do this,
but after doing a little bit of research and using available open 
source as template,  biojava - cvs can do this now!

A "screenshot"  of two superimposed residues is available at:

http://www.sanger.ac.uk/Users/ap3/rotation_example.html


This is achieved by using the Jama library which is under us. gov. 
public domain license (i.e. do whatever you want).
  It is located at http://math.nist.gov/javanumerics/jama/

I  added the few files from this package to the biojava cvs repository 
under org.biojava.structure.jama.
  I thought that biojava should not have yet another .jar dependency, so 
inclusion of the code is better.

There is now also a class called SVDSuperimposer. It is heavily 
inspired by some code available from our friends
at Biopython.... :-) Thanks also to Peter Lackner for providing an 
example for how to calculate "virtual"
  CB atoms.


Now Tamas: back to your problem. I think you want to do something like 
the code below:

Regards,
Andreas


  try{

             // get two amino acids from somewhere
             String filename   =  "/Users/ap3/WORK/PDB/5pti.pdb" ;

             PDBFileReader pdbreader = new PDBFileReader();
             Structure struc = pdbreader.getStructure(filename);
             Group g1 = (Group)struc.getChain(0).getGroup(56);
             Group g2 = (Group)struc.getChain(0).getGroup(21);

             if ( g1.getPDBName().equals("GLY")){
                 if ( g1 instanceof AminoAcid){
                     Atom cb = Calc.createVirtualCBAtom((AminoAcid)g1);
                     g1.addAtom(cb);
                 }
             }

             if ( g2.getPDBName().equals("GLY")){
                 if ( g2 instanceof AminoAcid){
                     Atom cb = Calc.createVirtualCBAtom((AminoAcid)g2);
                     g2.addAtom(cb);
                 }
             }



             System.out.println(g1);
             System.out.println(g2);

             // convert the Groups to Atom arrays
             Atom[] atoms1 = new Atom[3];
             Atom[] atoms2 = new Atom[3];

             atoms1[0] = g1.getAtom("N");
             atoms1[1] = g1.getAtom("CA");
             atoms1[2] = g1.getAtom("CB");


             atoms2[0] = g2.getAtom("N");
             atoms2[1] = g2.getAtom("CA");
             atoms2[2] = g2.getAtom("CB");


             // and do the SVD ...
             SVDSuperimposer svds = new SVDSuperimposer(atoms1,atoms2);

             // the rotation matrix to be applied to group2
             Matrix rotMatrix = svds.getRotation();

             // and the vector to shift group2
             Atom tranMatrix = svds.getTranslation();


             // now we have all the info to perform the rotations ...

             // clone group2 - we want to preserve the original coords 
for the output later.
             Group newGroup = (Group)g2.clone();


             // and rotate it
             Calc.rotate(newGroup,rotMatrix);

             //    shift the group ...
             Calc.shift(newGroup,tranMatrix);

             // that's it!


             ///
             // now we finish up with doing some output:
             // write to a file to view in a viewer
             String outputfile = "/Users/ap3/WORK/PDB/rotated.pdb";

             FileOutputStream out= new FileOutputStream(outputfile);
             PrintStream p =  new PrintStream( out );

             // create a new structure that contains the data to be 
written to the file.
             Structure newstruc = new StructureImpl();

             // add the group1
             Chain c1 = new ChainImpl();
             c1.setName("A");
             c1.addGroup(g1);
             newstruc.addChain(c1);

             // add the now correctly positioned group2
             Chain c2 = new ChainImpl();
             c2.setName("B");
             c2.addGroup(newGroup);
             newstruc.addChain(c2);


             // show where the group was originally ...
             Chain c3 = new ChainImpl();
             c3.setName("C");
             //c3.addGroup(g1);
             c3.addGroup(g2);

             newstruc.addChain(c3);
             p.println(newstruc.toPDB());

             p.close();

             System.out.println("wrote to file " + outputfile);

         } catch (Exception e){
             e.printStackTrace();
         }


On 2 Dec 2005, at 13:02, Tamas Horvath wrote:

> Thanks for the codes! I've noticed the methods in Calc, but my main 
> question is the following. Let's say I've got a primitive library of 
> AminoAcides. They stored as a group, they have all the atoms. When I'm 
> mutating the chain, I want to keep the backbone atoms in place, so as 
> far as your mutate method goes it's ok. But now I want to replace the 
> sidechain. In order to do that, I'd shift and rotate the desired AA in 
> place (Cbs would be identical and the other backbone atoms as close as 
> possible), and then copy the sidechain atoms to the mutated AA... (I 
> hope that's clear)
>
> So do I have to wrap my Group objects to a Chain/Structure object in 
> order to shift and rotate them?
>
> I don't really get how the rotation is supposed to work... what is 
> exactly the matrix it asks for?
-----------------------------------------------------------------------

Andreas Prlic      Wellcome Trust Sanger Institute
                               Hinxton, Cambridge CB10 1SA, UK
			 +44 (0) 1223 49 6891



More information about the Biojava-l mailing list