001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 */ 021package org.biojava.nbio.structure.align.gui; 022 023import java.util.List; 024 025import org.biojava.nbio.structure.Atom; 026import org.biojava.nbio.structure.AtomImpl; 027import org.biojava.nbio.structure.Calc; 028import org.biojava.nbio.structure.Group; 029import org.biojava.nbio.structure.StructureException; 030import org.biojava.nbio.structure.StructureTools; 031import org.biojava.nbio.structure.align.AFPTwister; 032import org.biojava.nbio.structure.align.fatcat.FatCatFlexible; 033import org.biojava.nbio.structure.align.fatcat.FatCatRigid; 034import org.biojava.nbio.structure.align.gui.jmol.StructureAlignmentJmol; 035import org.biojava.nbio.structure.align.model.AFPChain; 036import org.biojava.nbio.structure.jama.Matrix; 037 038public class StructureAlignmentDisplay { 039 040 /** Display an AFPChain alignment 041 * 042 * @param afpChain 043 * @param ca1 044 * @param ca2 045 * @return a StructureAlignmentJmol instance 046 * @throws StructureException 047 */ 048 public static StructureAlignmentJmol display(AFPChain afpChain, Atom[] ca1, Atom[] ca2) throws StructureException { 049 050 if ( ca1.length < 1 || ca2.length < 1){ 051 throw new StructureException("length of atoms arrays is too short! " + ca1.length + "," + ca2.length); 052 } 053 054 Group[] twistedGroups = prepareGroupsForDisplay(afpChain, ca1, ca2); 055 056 List<Group> hetatms = StructureTools.getUnalignedGroups(ca1); 057 List<Group> hetatms2 = StructureTools.getUnalignedGroups(ca2); 058 059 return DisplayAFP.display(afpChain, twistedGroups, ca1, ca2, hetatms, hetatms2); 060 061 } 062 063 /** Rotate the Atoms/Groups so they are aligned for the 3D visualisation 064 * 065 * @param afpChain 066 * @param ca1 067 * @param ca2 068 * @return an array of Groups that are transformed for 3D display 069 * @throws StructureException 070 */ 071 public static Group[] prepareGroupsForDisplay(AFPChain afpChain, Atom[] ca1, Atom[] ca2) throws StructureException{ 072 073 074 if ( afpChain.getBlockRotationMatrix().length == 0 ) { 075 // probably the alignment is too short! 076 System.err.println("No rotation matrix found to rotate 2nd structure!"); 077 afpChain.setBlockRotationMatrix(new Matrix[]{Matrix.identity(3, 3)}); 078 afpChain.setBlockShiftVector(new Atom[]{new AtomImpl()}); 079 } 080 081 // List of groups to be rotated according to the alignment 082 Group[] twistedGroups = new Group[ ca2.length]; 083 084 //int blockNum = afpChain.getBlockNum(); 085 086 int i = -1; 087 088 // List of groups from the structure not included in ca2 (e.g. ligands) 089 // Will be rotated according to first block 090 List<Group> hetatms2 = StructureTools.getUnalignedGroups(ca2); 091 092 if ( (afpChain.getAlgorithmName().equals(FatCatRigid.algorithmName) ) || (afpChain.getAlgorithmName().equals(FatCatFlexible.algorithmName) ) ){ 093 094 for (Atom a: ca2){ 095 i++; 096 twistedGroups[i]=a.getGroup(); 097 098 } 099 100 twistedGroups = AFPTwister.twistOptimized(afpChain, ca1, ca2); 101 102 //} else if (( blockNum == 1 ) || (afpChain.getAlgorithmName().equals(CeCPMain.algorithmName))) { 103 } else { 104 105 Matrix m = afpChain.getBlockRotationMatrix()[ 0]; 106 Atom shift = afpChain.getBlockShiftVector() [ 0 ]; 107 108 shiftCA2(afpChain, ca2, m,shift, twistedGroups); 109 110 } 111 112 if ( afpChain.getBlockNum() > 0){ 113 114 // Superimpose ligands relative to the first block 115 if( hetatms2.size() > 0 ) { 116 117 if ( afpChain.getBlockRotationMatrix().length > 0 ) { 118 119 Matrix m1 = afpChain.getBlockRotationMatrix()[0]; 120 //m1.print(3,3); 121 Atom vector1 = afpChain.getBlockShiftVector()[0]; 122 //System.out.println("shift vector:" + vector1); 123 124 for ( Group g : hetatms2){ 125 Calc.rotate(g, m1); 126 Calc.shift(g,vector1); 127 } 128 } 129 } 130 } 131 132 return twistedGroups; 133 } 134 135 /** only shift CA positions. 136 * 137 */ 138 public static void shiftCA2(AFPChain afpChain, Atom[] ca2, Matrix m, Atom shift, Group[] twistedGroups) { 139 140 int i = -1; 141 for (Atom a: ca2){ 142 i++; 143 Group g = a.getGroup(); 144 145 Calc.rotate(g,m); 146 Calc.shift(g, shift); 147 148 if (g.hasAltLoc()){ 149 for (Group alt: g.getAltLocs()){ 150 for (Atom alta : alt.getAtoms()){ 151 if ( g.getAtoms().contains(alta)) 152 continue; 153 Calc.rotate(alta,m); 154 Calc.shift(alta,shift); 155 } 156 } 157 } 158 twistedGroups[i]=g; 159 } 160 } 161 162}