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 * Created on Jan 28, 2006 021 * 022 */ 023package org.biojava.nbio.structure.align.pairwise; 024 025 026import org.biojava.nbio.structure.*; 027import org.biojava.nbio.structure.align.StrucAligParameters; 028import org.biojava.nbio.structure.align.helper.AligMatEl; 029import org.biojava.nbio.structure.align.helper.IndexPair; 030import org.biojava.nbio.structure.align.helper.JointFragments; 031import org.biojava.nbio.structure.geometry.Matrices; 032import org.biojava.nbio.structure.geometry.SuperPositions; 033import org.biojava.nbio.structure.jama.Matrix; 034 035import java.io.Serializable; 036import java.text.DecimalFormat; 037import java.util.List; 038import java.util.logging.Logger; 039 040import javax.vecmath.Matrix4d; 041 042/** 043 * Implements a class which handles one possible (alternative) solution. 044 * 045 * Alternative alignments arise from different seed 046 * alignments or seed FPairs. The AltAlg class contains methods 047 * for refinement (Dynamic Programming based) and filtering 048 * (i.e. removing probably wrongly matched APairs). In the refinement 049 * phase, different seed alignments can converge to the same solution. 050 * 051 * @author Andreas Prlic, 052 * @author Peter Lackner (original Python and C code) 053 * @since 3:04:26 PM 054 * @version %I% %G% 055 */ 056public class AlternativeAlignment implements Serializable{ 057 058 059 /** 060 * 061 */ 062 private static final long serialVersionUID = -6226717654562221241L; 063 064 int[] idx1; 065 int[] idx2; 066 String[] pdbresnum1; 067 String[] pdbresnum2; 068 //short[] alig1; 069 //short[] alig2; 070 071 int nfrags; 072 Atom center; 073 Matrix rot; 074 Atom tr; 075 076 077 // the scores... 078 int gaps0; 079 int eqr0; 080 int rms0; 081 int joined; 082 int percId; 083 int cluster; 084 float score; 085 IndexPair[] aligpath; 086 int fromia; 087 Matrix currentRotMatrix; 088 Atom currentTranMatrix; 089 090 double rms; 091 092 Matrix distanceMatrix; 093 094 public static Logger logger = Logger.getLogger("org.biojava.nbio.structure.align"); 095 096 097 public AlternativeAlignment() { 098 super(); 099 100 nfrags = 0; 101 aligpath = new IndexPair[0]; 102 //alig1 = new short[0]; 103 //alig2 = new short[0]; 104 idx1 = new int[0]; 105 idx2 = new int[0]; 106 107 center = new AtomImpl(); 108 rot = null; 109 tr = new AtomImpl(); 110 eqr0 = -99; 111 rms0 = 99; 112 joined = 0; 113 gaps0 = -99; 114 fromia = 0; 115 116 currentRotMatrix = new Matrix(0,0); 117 currentTranMatrix = new AtomImpl(); 118 119 distanceMatrix = new Matrix(0,0); 120 } 121 122 123 124 125 /** print the idx positions of this alignment 126 * 127 * @return a String representation 128 */ 129 @Override 130 public String toString(){ 131 DecimalFormat d2 = new DecimalFormat(); 132 // the result can be localized. To change this and enforce UK local do... 133 //(DecimalFormat)NumberFormat.getInstance(java.util.Locale.UK); 134 d2.setMaximumIntegerDigits(3); 135 d2.setMinimumFractionDigits(2); 136 d2.setMaximumFractionDigits(2); 137 StringBuffer s = new StringBuffer(); 138 s.append("#" + getAltAligNumber() + 139 " cluster:" + cluster + 140 " eqr:" + getEqr() + 141 " rmsd:" + d2.format(getRmsd()) + 142 " %id:" + getPercId() + 143 " gaps:" + getGaps() + 144 " score:" + d2.format(score) ); 145 146 return s.toString(); 147 } 148 149 150 /** get the number of the cluster this alignment belongs to 151 * 152 * @return an int giving the number of the cluster 153 */ 154 public int getCluster() { 155 return cluster; 156 } 157 158 159 160 /** set the number of the cluster this alignment belongs to. 161 * All alignments in a cluster are quite similar. 162 * 163 * @param cluster the number of the cluster 164 */ 165 public void setCluster(int cluster) { 166 this.cluster = cluster; 167 } 168 169 170 171 172 public double getRmsd() { 173 return rms; 174 } 175 176 /** the rms in the structurally equivalent regions 177 * 178 * @param rms 179 */ 180 public void setRms(double rms) { 181 this.rms = rms; 182 } 183 184 /** the alignment score 185 * 186 * @return the score of this alignment 187 */ 188 public float getScore() { 189 return score; 190 } 191 192 public void setScore(float score) { 193 this.score = score; 194 } 195 196 197 /** return the number of gaps in this alignment 198 * 199 * @return the number of Gaps 200 */ 201 public int getGaps(){ 202 return gaps0; 203 } 204 205 /** returns the number of euqivalent residues in this alignment 206 * 207 * @return the number of equivalent residues 208 */ 209 public int getEqr(){ 210 return eqr0 ; 211 } 212 213 /** the positions of the structure equivalent positions in atom set 1 214 * 215 * @return the array of the positions 216 */ 217 public int[] getIdx1(){ 218 return idx1; 219 } 220 221 /** the positions of the structure equivalent atoms in atom set 2 222 * 223 * @return the array of the positions 224 */ 225 public int[] getIdx2(){ 226 return idx2; 227 } 228 229 public int getPercId() { 230 return percId; 231 } 232 233 public void setPercId(int percId) { 234 this.percId = percId; 235 } 236 237 /** Set apairs according to a seed position. 238 * 239 * @param l 240 * @param i 241 * @param j 242 */ 243 public void apairs_from_seed(int l,int i, int j){ 244 aligpath = new IndexPair[l]; 245 idx1 = new int[l]; 246 idx2 = new int[l]; 247 for (int x = 0 ; x < l ; x++) { 248 idx1[x]=i+x; 249 idx2[x]=j+x; 250 aligpath[x] = new IndexPair((short)(i+x),(short)(j+x)); 251 } 252 } 253 254 /** Set apairs according to a list of (i,j) tuples. 255 * 256 * @param jf a JoingFragment 257 */ 258 public void apairs_from_idxlst(JointFragments jf) { 259 List<int[]> il = jf.getIdxlist(); 260 //System.out.println("Alt Alig apairs_from_idxlst"); 261 262 aligpath = new IndexPair[il.size()]; 263 idx1 = new int[il.size()]; 264 idx2 = new int[il.size()]; 265 for (int i =0 ; i < il.size();i++) { 266 int[] p = il.get(i); 267 //System.out.print(" idx1 " + p[0] + " idx2 " + p[1]); 268 idx1[i] = p[0]; 269 idx2[i] = p[1]; 270 aligpath[i] = new IndexPair((short)p[0],(short)p[1]); 271 272 } 273 eqr0 = idx1.length; 274 //System.out.println("eqr " + eqr0); 275 gaps0 = count_gaps(idx1,idx2); 276 277 } 278 279 280 /** returns the sequential number of this alternative alignment 281 * 282 * @return the sequential number of this alternative alignment 283 */ 284 public int getAltAligNumber() { 285 return fromia; 286 } 287 288 public void setAltAligNumber(int fromia) { 289 this.fromia = fromia; 290 } 291 292 /** rotate and shift atoms with currentRotMatrix and current Tranmatrix 293 * 294 * @param ca 295 */ 296 private void rotateShiftAtoms(Atom[] ca){ 297 298 for (int i = 0 ; i < ca.length; i++){ 299 Atom c = ca[i]; 300 301 Calc.rotate(c,currentRotMatrix); 302 Calc.shift(c,currentTranMatrix); 303 //System.out.println("after " + c); 304 ca[i] = c; 305 } 306 //System.out.println("after " + ca[0]); 307 } 308 309 public void finish(StrucAligParameters params,Atom[]ca1,Atom[]ca2) throws StructureException{ 310 311 Atom[] ca3 = new Atom[ca2.length]; 312 for ( int i = 0 ; i < ca2.length;i++){ 313 ca3[i] = (Atom) ca2[i].clone(); 314 315 } 316 // do the inital superpos... 317 318 super_pos_alig(ca1,ca3,idx1,idx2,true); 319 rotateShiftAtoms(ca3); 320 321 calcScores(ca1,ca2); 322 logger.fine("eqr " + eqr0 + " " + gaps0 + " " +idx1[0] + " " +idx1[1]); 323 324 getPdbRegions(ca1,ca2); 325 326 } 327 328 public static Matrix getDistanceMatrix(Atom[] ca1, Atom[]ca2){ 329 330 int r = ca1.length; 331 int c = ca2.length; 332 333 Matrix out = new Matrix(r,c); 334 335 for (int i=0; i<r; i++) { 336 Atom a1 = ca1[i]; 337 for (int j=0;j<c;j++){ 338 Atom b1 = ca2[j]; 339 340 341 double d = Calc.getDistance(a1,b1); 342 out.set(i,j,d); 343 344 } 345 } 346 return out; 347 } 348 349 private Alignable getInitalStrCompAlignment( 350 Atom[] ca1, 351 Atom[]ca2, 352 StrucAligParameters params 353 ){ 354 355 int rows = ca1.length; 356 int cols = ca2.length; 357 358 float gapOpen = params.getGapOpen(); 359 float gapExtension = params.getGapExtension(); 360 float co = params.getCreate_co(); 361 362 Alignable al = new StrCompAlignment(rows,cols); 363 al.setGapExtCol(gapExtension); 364 al.setGapExtRow(gapExtension); 365 al.setGapOpenCol(gapOpen); 366 al.setGapOpenRow(gapOpen); 367 368 AligMatEl[][] aligmat = al.getAligMat(); 369 370 //System.out.println(rows + " " + cols ); 371 372 aligmat[0][cols] = new AligMatEl(); 373 aligmat[rows][0] = new AligMatEl(); 374 aligmat[rows][cols] = new AligMatEl(); 375 376 for (int i = 0; i < rows; i++) { 377 Atom a1 = ca1[i]; 378 379 aligmat[i][0] = new AligMatEl(); 380 //aligmat[i][cols] = new AligMatEl(); 381 382 for (int j = 0; j < cols; j++) { 383 //System.out.println("index " + i + " " + j); 384 aligmat[0][j] = new AligMatEl(); 385 386 Atom b1 = ca2[j]; 387 double d = 999; 388 389 d = Calc.getDistance(a1,b1); 390 391 392 AligMatEl e = new AligMatEl(); 393 if (d > co) { 394 e.setValue(0); 395 } else { 396 double s = 2 * co / ( 1 + ( d/co) * (d/co)) - co; 397 e.setValue((int) Math.round(Gotoh.ALIGFACTOR * s)); 398 } 399 aligmat[i+1][j+1] = e; 400 } 401 } 402 403 return al; 404 } 405 406 /*private Alignable getAlignableFromSimMatrix (Matrix sim,StrucAligParameters params){ 407 //System.out.println("align_NPE"); 408 409 float gapOpen = params.getGapOpen(); 410 float gapExtension = params.getGapExtension(); 411 412 int rows = sim.getRowDimension(); 413 int cols = sim.getColumnDimension(); 414 415 Alignable al = new StrCompAlignment(rows,cols); 416 al.setGapExtCol(gapExtension); 417 al.setGapExtRow(gapExtension); 418 al.setGapOpenCol(gapOpen); 419 al.setGapOpenRow(gapOpen); 420 //System.out.println("size of aligmat: " + rows+1 + " " + cols+1); 421 //AligMatEl[][] aligmat = new AligMatEl[rows+1][cols+1]; 422 AligMatEl[][] aligmat = al.getAligMat(); 423 424 for (int i = 0; i < rows; i++) { 425 for (int j = 0; j < cols; j++) { 426 427 int e=0; 428 //if ( ( i < rows) && 429 // ( j < cols)) { 430 //TODO: the ALIGFACTOR calc should be hidden in Gotoh!! 431 432 e = (int)Math.round(Gotoh.ALIGFACTOR * sim.get(i,j)); 433 //} 434 //System.out.println(e); 435 //AligMatEl am = new AligMatEl(); 436 aligmat[i+1][j+1].setValue(e); 437 //.setValue(e); 438 //am.setTrack(new IndexPair((short)-99,(short)-99)); 439 //igmat[i+1][j+1] = am; 440 441 } 442 } 443 //al.setAligMat(aligmat); 444 445 446 return al; 447 }*/ 448 /** Refinement procedure based on superposition and dynamic programming. 449 * Performs an iterative refinement. Several methods apply such a procedure, 450 * e.g. CE or ProSup. Here we additionally test for circular permutation, 451 * which are in the same frame of superposition as the optimal alignment. 452 * This feature may be switched off by setting permsize to -1. 453 * 454 * @param params the parameters 455 * @param ca1 atoms of structure 1 456 * @param ca2 atoms of structure 2 457 * @throws StructureException 458 */ 459 460 public void refine(StrucAligParameters params,Atom[]ca1,Atom[]ca2) throws StructureException{ 461 // System.out.println("refine Alternative Alignment #"+ getAltAligNumber()+" l1:" + ca1.length + " l2:" + ca2.length); 462 // for ( int i= 0 ; i < idx1.length;i++){ 463 // System.out.println(idx1[i] + " " + idx2[i]); 464 // } 465 466 // avoid any operations on the original Atoms ... 467 Atom[] ca3 = new Atom[ca2.length]; 468 for ( int i = 0 ; i < ca2.length;i++){ 469 ca3[i] = (Atom) ca2[i].clone(); 470 471 } 472 //Atom[] ca3 = (Atom[]) ca2.clone(); 473 474 // do the inital superpos... 475 476 super_pos_alig(ca1,ca3,idx1,idx2,false); 477 478 //JmolDisplay jmol1 = new JmolDisplay(ca1,ca2,"after first alig " ); 479 //jmol1.selectEquiv(idx1,idx2); 480 //int[] jmoltmp1 = idx1; 481 //int[] jmoltmp2 = idx2; 482 483 int lenalt =idx1.length; 484 int lenneu = aligpath.length; 485 //Matrix rmsalt = currentRotMatrix; 486 487 488 489 int ml = Math.max(ca1.length, ca3.length); 490 idx1 = new int[ml]; 491 idx2 = new int[ml]; 492 493 //int m1l = ca1.length; 494 //int m2l = ca3.length; 495 496 //Matrix sim = new Matrix(ca1.length,ca3.length,0); 497 498 int maxiter = params.getMaxIter(); 499 for (int iter = 0 ; iter< maxiter; iter++){ 500 501 float subscore = 0.0f; 502 503 rotateShiftAtoms(ca3); 504 505 // do the dynamic alignment... 506 Alignable ali = getInitalStrCompAlignment(ca1,ca3, params); 507 508 new Gotoh(ali); 509 510 this.score = ali.getScore(); 511 //System.out.println("score " + score); 512 IndexPair[] path = ali.getPath(); 513 514 int pathsize = ali.getPathSize(); 515 516 517 // now for a superimposable permutation. First we need to check the size and 518 // position of the quadrant left out by the optimal path 519 int firsta = path[0].getRow(); 520 int firstb = path[0].getCol(); 521 int lasta = path[pathsize-1].getRow(); 522 int lastb = path[pathsize-1].getCol(); 523 524 int quada_beg, quada_end, quadb_beg,quadb_end; 525 526 if ( firsta == 0){ 527 quada_beg = lasta +1; 528 quada_end = ca1.length -1; 529 quadb_beg = 0; 530 quadb_end = firstb-1; 531 } else { 532 quada_beg = 0; 533 quada_end = firsta-1; 534 quadb_beg = lastb+1; 535 quadb_end = ca3.length -1; 536 } 537 538 // if the unaligned quadrant is larger than permsize 539 int permsize = params.getPermutationSize(); 540 541 if ( permsize > 0 && 542 (quada_end - quada_beg >= permsize) && 543 ( quadb_end - quadb_beg >= permsize)) { 544 AligMatEl[][] aligmat = ali.getAligMat(); 545 Matrix submat = new Matrix(quada_end-quada_beg, quadb_end - quadb_beg) ; 546 //then we copy the score values of the quadrant into a new matrix 547 548 //System.out.println(quada_beg + " " + quada_end + " " +quadb_beg+" " + quadb_end); 549 //System.out.println(sim.getRowDimension() + " " + sim.getColumnDimension()); 550 Atom[] tmp1 = new Atom[quada_end - quada_beg ]; 551 Atom[] tmp2 = new Atom[quadb_end - quadb_beg ]; 552 553 for ( int s = quada_beg; s < quada_end; s++){ 554 //System.out.println(s + " " +( quada_end-s)); 555 tmp1[quada_end - s -1] = ca1[s]; 556 for ( int t = quadb_beg; t < quadb_end; t++){ 557 if ( s == quada_beg ) 558 tmp2[quadb_end - t -1 ] = ca3[t]; 559 560 //System.out.println(s+" " +t); 561 //double val = sim.get(s,t); 562 double val = aligmat[s][t].getValue(); 563 submat.set(s-quada_beg,t-quadb_beg,val); 564 } 565 } 566 // and perform a dp alignment again. (Note, that we fix the superposition). 567 568 //Alignable subali = getAlignableFromSimMatrix(submat,params); 569 Alignable subali = getInitalStrCompAlignment(tmp1, tmp2, params); 570 subscore = subali.getScore(); 571 //System.out.println("join score" + score + " " + subscore); 572 this.score = score+subscore; 573 574 IndexPair[] subpath = subali.getPath(); 575 int subpathsize = subali.getPathSize(); 576 for ( int p=0;p<subpath.length;p++){ 577 IndexPair sp = subpath[p]; 578 sp.setRow((short)(sp.getRow()+quada_beg)); 579 sp.setCol((short)(sp.getCol()+quadb_beg)); 580 } 581 582 // now we join the two solutions 583 if ( subpathsize > permsize){ 584 IndexPair[] wholepath = new IndexPair[pathsize+subpathsize]; 585 for ( int t=0; t < pathsize; t++){ 586 wholepath[t] = path[t]; 587 } 588 for ( int t=0 ; t < subpathsize; t++){ 589 wholepath[t+pathsize] = subpath[t]; 590 } 591 pathsize += subpathsize; 592 path = wholepath; 593 ali.setPath(path); 594 ali.setPathSize(pathsize); 595 } 596 597 } 598 599 600 int j =0 ; 601 //System.out.println("pathsize,path " + pathsize + " " + path.length); 602 603 for (int i=0; i < pathsize; i++){ 604 int x = path[i].getRow(); 605 int y = path[i].getCol(); 606 //System.out.println(x+ " " + y); 607 double d = Calc.getDistance(ca1[x], ca3[y]); 608 //double d = dismat.get(x,y); 609 // now we apply the evaluation distance cutoff 610 if ( d < params.getEvalCutoff()){ 611 //System.out.println("j:"+j+ " " + x+" " + y + " " + d ); 612 613 idx1[j] = x; 614 idx2[j] = y; 615 j+=1; 616 } 617 } 618 619 lenneu = j; 620 //System.out.println("lenalt,neu:" + lenalt + " " + lenneu); 621 622 623 int[] tmpidx1 = new int[j]; 624 int[] tmpidx2 = new int[j]; 625 //String idx1str ="idx1: "; 626 //String idx2str ="idx2: "; 627 for (int i = 0 ; i<j;i++){ 628 //idx1str += idx1[i]+ " "; 629 //idx2str += idx2[i]+ " "; 630 tmpidx1[i] = idx1[i]; 631 tmpidx2[i] = idx2[i]; 632 } 633 //System.out.println(idx1str); 634 //System.out.println(idx2str); 635 //jmol.selectEquiv(idx1,idx2); 636 637 //if ( j > 0) 638 // System.out.println("do new superimpos " + idx1.length + " " + idx2.length + " " + idx1[0] + " " + idx2[0]); 639 super_pos_alig(ca1,ca3,tmpidx1,tmpidx2,false); 640 641 this.aligpath = path; 642 643 if (lenneu == lenalt) 644 break; 645 646 } 647 648 649 650 idx1 = (int[]) FragmentJoiner.resizeArray(idx1,lenneu); 651 idx2 = (int[]) FragmentJoiner.resizeArray(idx2,lenneu); 652 // new ... get rms... 653 // now use the original atoms to get the rotmat relative to the original structure... 654 super_pos_alig(ca1,ca2,idx1,idx2,true); 655 eqr0 = idx1.length; 656 gaps0 = count_gaps(idx1,idx2); 657 658 getPdbRegions(ca1,ca2); 659 //System.out.println("eqr " + eqr0 + " aligpath len:"+aligpath.length+ " gaps:" + gaps0 + " score " + score); 660 } 661 662 private void getPdbRegions(Atom[] ca1, Atom[] ca2){ 663 pdbresnum1 = new String[idx1.length]; 664 pdbresnum2 = new String[idx2.length]; 665 666 for (int i =0 ; i < idx1.length;i++){ 667 Atom a1 = ca1[idx1[i]]; 668 Atom a2 = ca2[idx2[i]]; 669 Group p1 = a1.getGroup(); 670 Group p2 = a2.getGroup(); 671 Chain c1 = p1.getChain(); 672 Chain c2 = p2.getChain(); 673 674 String cid1 = c1.getId(); 675 String cid2 = c2.getId(); 676 677 String pdb1 = p1.getResidueNumber().toString(); 678 String pdb2 = p2.getResidueNumber().toString(); 679 680 681 if ( ! cid1.equals(" ")) 682 pdb1 += ":" + cid1; 683 684 685 if ( ! cid2.equals(" ")) 686 pdb2 += ":" + cid2; 687 688 689 pdbresnum1[i] = pdb1; 690 pdbresnum2[i] = pdb2; 691 } 692 } 693 694 695 public String[] getPDBresnum1() { 696 return pdbresnum1; 697 } 698 699 700 701 702 public void setPDBresnum1(String[] pdbresnum1) { 703 this.pdbresnum1 = pdbresnum1; 704 } 705 706 707 708 709 public String[] getPDBresnum2() { 710 return pdbresnum2; 711 } 712 713 714 715 716 public void setPDBresnum2(String[] pdbresnum2) { 717 this.pdbresnum2 = pdbresnum2; 718 } 719 720 721 722 723 /** Count the number of gaps in an alignment represented by idx1,idx2. 724 * 725 * @param idx1 726 * @param idx2 727 * @return the number of gaps in this alignment 728 */ 729 private int count_gaps(int[] i1, int[] i2){ 730 731 int i0 = i1[0]; 732 int j0 = i2[0]; 733 int gaps = 0; 734 for (int i =1 ; i<i1.length;i++ ){ 735 if ( Math.abs(i1[i]-i0) != 1 || 736 ( Math.abs(i2[i]-j0) != 1)){ 737 gaps +=1; 738 } 739 i0 = i1[i]; 740 j0 = i2[i]; 741 } 742 743 return gaps; 744 } 745 746 747 748 public void calculateSuperpositionByIdx(Atom[] ca1, Atom[] ca2)throws StructureException { 749 750 super_pos_alig(ca1,ca2,idx1,idx2,false); 751 752 } 753 754 /** Superimposes two molecules according to residue index list idx1 and idx2. 755 * Does not change the original coordinates. 756 * as an internal result the rotation matrix and shift vectors for are set 757 * 758 * @param ca1 Atom set 1 759 * @param ca2 Atom set 2 760 * @param idx1 idx positions in set1 761 * @param idx2 idx positions in set2 762 * @param getRMS a flag if the RMS should be calculated 763 * @throws StructureException 764 */ 765 766 767 768 private void super_pos_alig(Atom[]ca1,Atom[]ca2,int[] idx1, int[] idx2, boolean getRMS) throws StructureException{ 769 770 //System.out.println("superpos alig "); 771 Atom[] ca1subset = new Atom[idx1.length]; 772 Atom[] ca2subset = new Atom[idx2.length]; 773 774 for (int i = 0 ; i < idx1.length;i++){ 775 //System.out.println("idx1 "+ idx1[i] + " " + idx2[i]); 776 int pos1 = idx1[i]; 777 int pos2 = idx2[i]; 778 779 ca1subset[i] = ca1[pos1]; 780 ca2subset[i] = (Atom) ca2[pos2].clone(); 781 } 782 783 Matrix4d trans = SuperPositions.superpose(Calc.atomsToPoints(ca1subset), 784 Calc.atomsToPoints(ca2subset)); 785 this.currentRotMatrix = Matrices.getRotationJAMA(trans); 786 this.currentTranMatrix = Calc.getTranslationVector(trans); 787 //currentRotMatrix.print(3,3); 788 if ( getRMS) { 789 rotateShiftAtoms(ca2subset); 790 this.rms = Calc.rmsd(ca1subset,ca2subset); 791 } 792 793 794 } 795 796 797 /** returns the rotation matrix that needs to be applied to structure 2 to rotate on structure 1 798 * 799 * @return the rotation Matrix 800 */ 801 public Matrix getRotationMatrix(){ 802 return currentRotMatrix; 803 } 804 805 /** returns the shift vector that has to be applied on structure to to shift on structure one 806 * 807 * @return the shift vector 808 */ 809 public Atom getShift(){ 810 return currentTranMatrix; 811 } 812 813 814 815 /** calculates scores for this alignment ( %id ) 816 * @param ca1 set of Atoms for molecule 1 817 * @param ca2 set of Atoms for molecule 2 818 819 */ 820 public void calcScores(Atom[] ca1, Atom[] ca2){ 821 eqr0 = idx1.length; 822 gaps0 = count_gaps(idx1,idx2); 823 824 percId = 0; 825 // calc the % id 826 for (int i=0 ; i< idx1.length; i++){ 827 Atom a1 = ca1[idx1[i]]; 828 Atom a2 = ca2[idx2[i]]; 829 830 Group g1 = a1.getGroup(); 831 Group g2 = a2.getGroup(); 832 if ( g1.getPDBName().equals(g2.getPDBName())){ 833 percId++; 834 } 835 836 } 837 } 838 839 840 841 /** create an artifical Structure object that contains the two 842 * structures superimposed onto each other. Each structure is in a separate model. 843 * Model 1 is structure 1 and Model 2 is structure 2. 844 * 845 * @param s1 the first structure. its coordinates will not be changed 846 * @param s2 the second structure, it will be cloned and the cloned coordinates will be rotated according to the alignment results. 847 * @return composite structure containing the 2 aligned structures as a models 1 and 2 848 */ 849 public Structure getAlignedStructure(Structure s1, Structure s2){ 850 // do not change the original coords .. 851 Structure s3 = s2.clone(); 852 853 currentRotMatrix.print(3,3); 854 855 Calc.rotate(s3, currentRotMatrix); 856 Calc.shift( s3, currentTranMatrix); 857 858 Structure newpdb = new StructureImpl(); 859 newpdb.setPDBCode("Java"); 860 newpdb.setName("Aligned with BioJava"); 861 862 863 newpdb.addModel(s1.getChains(0)); 864 newpdb.addModel(s3.getChains(0)); 865 866 return newpdb; 867 868 } 869 870 /** converts the alignment to a PDB file 871 * each of the structures will be represented as a model. 872 * 873 * 874 * @param s1 875 * @param s2 876 * @return a PDB file as a String 877 */ 878 public String toPDB(Structure s1, Structure s2){ 879 880 881 Structure newpdb = getAlignedStructure(s1, s2); 882 883 return newpdb.toPDB(); 884 } 885 886 887 888 /** The distance matrix this alignment is based on 889 * 890 * @return a Matrix object. 891 */ 892 public Matrix getDistanceMatrix() { 893 return distanceMatrix; 894 } 895 896 897 898 /** The distance matrix this alignment is based on 899 * 900 * @param distanceMatrix 901 */ 902 public void setDistanceMatrix(Matrix distanceMatrix) { 903 this.distanceMatrix = distanceMatrix; 904 } 905 906 907 908 909 public IndexPair[] getPath() { 910 return aligpath; 911 } 912 913 914 915} 916