001/* 002 * PDB web 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 * 015 * Created on Jun 17, 2009 016 * Created by ap3 017 * 018 */ 019package org.biojava.nbio.structure.align.model; 020 021import org.biojava.nbio.structure.Atom; 022import org.biojava.nbio.structure.align.ce.CeMain; 023import org.biojava.nbio.structure.align.ce.CeSideChainMain; 024import org.biojava.nbio.structure.align.util.AFPAlignmentDisplay; 025import org.biojava.nbio.structure.jama.Matrix; 026 027import java.io.Serializable; 028import java.util.ArrayList; 029import java.util.Arrays; 030import java.util.List; 031import java.util.Map; 032 033/** 034 * A bean to contain the core of a structure alignment. 035 * The FatCat aligner class is working on the AFPChain class. 036 * 037 * @author Andreas Prlic 038 * @author Aleix Lafita 039 * 040 */ 041public class AFPChain implements Serializable, Cloneable { 042 043 private static final long serialVersionUID = -4474029015606617947L; 044 public static final String newline = System.getProperty("line.separator"); 045 public static final String UNKNOWN_ALGORITHM = "unknown"; 046 047 private String algorithmName; 048 private String version; 049 050 private String name1; 051 private String name2; 052 private long ioTime; 053 private long calculationTime; 054 private long id; 055 056 // results: 057 private double alignScore; 058 private double alignScoreUpdate; 059 private int afpChainTwiNum; 060 061 // end of results 062 private double tmScore; 063 064 // utility 065 private int minLen ; // the length of the shorter 2 proteins. 066 067 068 private List<AFP> afpSet; 069 private int[][] afpIndex; 070 private int[][] afpAftIndex; 071 private int[][] afpBefIndex; 072 073 private Matrix disTable1; 074 private Matrix disTable2; 075 076 private int[] twi = null ; //the number of twists making the best score ending at each AFP 077 078 private int afpChainLen; 079 private int[] afpChainList; 080 private double[] afpChainTwiBin; 081 private double[] afpChainTwiList; 082 private double chainRmsd; 083 084 private int chainLen,misLen,gapLen; 085 private int blockNum; //the final block number 086 private int blockNumIni; //block number before block clustering and split 087 private int blockNumClu; //block number after clustering blocks 088 private int blockNumSpt; //block number after spliting blocks 089 private double[] blockRmsd; //the RMSD of each block 090 private int[] block2Afp; //the index of afp for each block 091 private int[] blockSize; //the number of AFPs involved in a block 092 private double[] blockScore; //the score associated with each block 093 private int[] blockGap; //the gaps in each block 094 private int[] blockResSize; //the number of residues involved in a block 095 private int[][][] blockResList;//the list of AFP for each block 096 private Matrix[] blockRotationMatrix; 097 private Atom[] blockShiftVector; 098 099 private int focusResn; //the size of the set 100 private int[] focusRes1; //the residues from protein 1 101 private int[] focusRes2; //the residues from protein 2 102 private int focusAfpn; //the AFP number 103 private int[] focusAfpList; //the AFP list 104 105 private boolean shortAlign; 106 107 private String [][][] pdbAln; // only needed temp. during XML serialization, since we don;t have coordinates loaded at that time and can map from PDB res numbers to atom positions. 108 private int[][][] optAln; 109 private int[] optLen ; 110 private double[] optRmsd ; 111 private int optLength; 112 113 private char[] alnsymb; 114 private char[] alnseq1; 115 private char[] alnseq2; 116 private int alnLength; 117 private int alnbeg1; 118 private int alnbeg2; 119 120 private int totalLenIni; 121 private int totalLenOpt = 0; 122 123 private double totalRmsdIni; 124 private double totalRmsdOpt; 125 126 private int ca1Length; 127 private int ca2Length; 128 129 // this one is special. it comes from the FatCatParameters... 130 // default is flexible alignment... 131 private int maxTra = 5; 132 133 private Double conn; 134 private Double dvar; 135 136 private double probability; 137 private double identity; 138 private double similarity; 139 private double normAlignScore; 140 141 private int myResultsEQR; 142 private int myResultsSimilarity1; 143 private int myResultsSimilarity2; 144 145 // Mark whether the alignment topology is sequential 146 // false if a circular permutation has occured 147 private boolean sequentialAlignment; 148 149 // background distances 150 private Matrix distanceMatrix; 151 152 private String description2; 153 154 /** 155 * Construction of an AFPChain needs the algorithm name, since downstream 156 * analysis methods (scores, display, etc) behave differently if the 157 * alignment is flexible (created with FatCat). 158 * 159 * @param algorithmName 160 */ 161 public AFPChain(String algorithmName){ 162 this.algorithmName = algorithmName; 163 init(); 164 } 165 166 /** 167 * Copy constructor 168 * @param o AFPChain to duplicate 169 */ 170 public AFPChain(AFPChain o) { 171 this.algorithmName = o.algorithmName; 172 this.version = o.version; 173 this.name1 = o.name1; 174 this.name2 = o.name2; 175 this.ioTime = o.ioTime; 176 this.calculationTime = o.calculationTime; 177 this.id = o.id; 178 this.alignScore = o.alignScore; 179 this.alignScoreUpdate = o.alignScoreUpdate; 180 this.afpChainTwiNum = o.afpChainTwiNum; 181 this.minLen = o.minLen; 182 this.afpSet = new ArrayList<AFP>(o.afpSet); 183 this.afpIndex = o.afpIndex == null? null: o.afpIndex.clone(); 184 this.afpAftIndex = o.afpAftIndex == null? null: o.afpAftIndex.clone(); 185 this.afpBefIndex = o.afpBefIndex == null? null: o.afpBefIndex.clone(); 186 this.disTable1 = o.disTable1 == null? null: (Matrix) o.disTable1.clone(); 187 this.disTable2 = o.disTable2 == null? null: (Matrix) o.disTable2.clone(); 188 this.twi = o.twi == null ? null : o.twi.clone(); 189 this.afpChainLen = o.afpChainLen; 190 this.afpChainList = o.afpChainList == null? null: o.afpChainList.clone(); 191 this.afpChainTwiBin = o.afpChainTwiBin == null? null: o.afpChainTwiBin.clone(); 192 this.afpChainTwiList = o.afpChainTwiList == null? null: o.afpChainTwiList.clone(); 193 this.chainRmsd = o.chainRmsd; 194 this.chainLen = o.chainLen; 195 this.misLen = o.misLen; 196 this.gapLen = o.gapLen; 197 this.blockNum = o.blockNum; 198 this.blockNumIni = o.blockNumIni; 199 this.blockNumClu = o.blockNumClu; 200 this.blockNumSpt = o.blockNumSpt; 201 this.blockRmsd = o.blockRmsd == null ? null : o.blockRmsd.clone(); 202 this.block2Afp = o.block2Afp == null ? null : o.block2Afp.clone(); 203 this.blockSize = o.blockSize == null ? null : o.blockSize.clone(); 204 this.blockScore = o.blockScore == null ? null : o.blockScore.clone(); 205 this.blockGap = o.blockGap == null ? null : o.blockGap.clone(); 206 this.blockResSize = o.blockResSize == null ? null : o.blockResSize.clone(); 207 this.blockResList = o.blockResList == null ? null : o.blockResList.clone(); 208 this.blockRotationMatrix = o.blockRotationMatrix == null ? null : o.blockRotationMatrix.clone(); 209 this.blockShiftVector = o.blockShiftVector == null ? null : o.blockShiftVector.clone(); 210 this.focusResn = o.focusResn; 211 this.focusRes1 = o.focusRes1 == null ? null : o.focusRes1.clone(); 212 this.focusRes2 = o.focusRes2 == null ? null : o.focusRes2.clone(); 213 this.focusAfpn = o.focusAfpn; 214 this.focusAfpList = o.focusAfpList == null ? null : o.focusAfpList.clone(); 215 this.shortAlign = o.shortAlign; 216 this.pdbAln = o.pdbAln == null ? null : o.pdbAln.clone(); 217 this.optAln = o.optAln == null ? null : o.optAln.clone(); 218 this.optLen = o.optLen == null ? null : o.optLen.clone(); 219 this.optRmsd = o.optRmsd == null ? null : o.optRmsd.clone(); 220 this.optLength = o.optLength; 221 this.alnsymb = o.alnsymb == null ? null : o.alnsymb.clone(); 222 this.alnseq1 = o.alnseq1 == null ? null : o.alnseq1.clone(); 223 this.alnseq2 = o.alnseq2 == null ? null : o.alnseq2.clone(); 224 this.alnLength = o.alnLength; 225 this.alnbeg1 = o.alnbeg1; 226 this.alnbeg2 = o.alnbeg2; 227 this.totalLenIni = o.totalLenIni; 228 this.totalLenOpt = o.totalLenOpt; 229 this.totalRmsdIni = o.totalRmsdIni; 230 this.totalRmsdOpt = o.totalRmsdOpt; 231 this.ca1Length = o.ca1Length; 232 this.ca2Length = o.ca2Length; 233 this.maxTra = o.maxTra; 234 this.conn = new Double(o.conn); 235 this.dvar = new Double(o.dvar); 236 this.probability = o.probability; 237 this.identity = o.identity; 238 this.similarity = o.similarity; 239 this.normAlignScore = o.normAlignScore; 240 this.myResultsEQR = o.myResultsEQR; 241 this.myResultsSimilarity1 = o.myResultsSimilarity1; 242 this.myResultsSimilarity2 = o.myResultsSimilarity2; 243 this.distanceMatrix = o.distanceMatrix; 244 } 245 246 /** 247 * Creates and returns a copy of this object. 248 */ 249 @Override 250 public Object clone() { 251 return new AFPChain(this); 252 } 253 254 public long getId() 255 { 256 return id; 257 } 258 public void setId(long id) 259 { 260 this.id = id; 261 } 262 263 public String toCE(Atom[] ca1, Atom[]ca2) { 264 265 return AfpChainWriter.toCE(this,ca1,ca2); 266 267 } 268 269 public String toRotMat(){ 270 271 return AfpChainWriter.toRotMat(this); 272 } 273 274 public String toFatcat(Atom[] ca1, Atom[]ca2){ 275 276 return AfpChainWriter.toFatCat(this,ca1,ca2); 277 278 } 279 280 public String toDBSearchResult(){ 281 282 return AfpChainWriter.toDBSearchResult(this); 283 } 284 285 protected void calcSimilarity() { 286 Map<String,Double> idMap = AFPAlignmentDisplay.calcIdSimilarity(alnseq1,alnseq2,alnLength); 287 288 //probability = idMap.get("probability"); 289 similarity = idMap.get("similarity"); 290 identity = idMap.get("identity"); 291 292 } 293 294 295 296 297 /** 298 * Get the number of structurally equivalent residues 299 * 300 * @return nr of EQR 301 */ 302 public int getNrEQR(){ 303 304 if (myResultsEQR < 0){ 305 if ( optLen == null) { 306 myResultsEQR = 0; 307 return 0; 308 } 309 310 int nrEqr = 0; 311 for(int bk = 0; bk < blockNum; bk ++) { 312 313 for ( int i=0;i< optLen[bk];i++){ 314 nrEqr++; 315 } 316 } 317 myResultsEQR = nrEqr; 318 } 319 return myResultsEQR; 320 } 321 322 /** Get the coverage of protein 1 with the alignment 323 * 324 * @return percentage of coverage, between 0 and 100. 325 */ 326 public int getCoverage1(){ 327 if ( myResultsSimilarity1 < 0 ) { 328 int distance = ca1Length + ca2Length - 2 * getNrEQR(); 329 330 int similarity = (ca1Length + ca2Length - distance ) / 2; 331 332 myResultsSimilarity1 = Math.round(similarity /(float) ca1Length * 100); 333 } 334 return myResultsSimilarity1; 335 } 336 337 /** Get the coverage of protein 2 with the alignment 338 * 339 * @return percentage of coverage, between 0 and 100. 340 */ 341 public int getCoverage2(){ 342 if ( myResultsSimilarity2 < 0 ) { 343 344 345 int distance = ca1Length + ca2Length - 2 * getNrEQR(); 346 347 int similarity = (ca1Length + ca2Length - distance ) / 2; 348 myResultsSimilarity2 = Math.round(similarity /(float) ca2Length * 100); 349 } 350 return myResultsSimilarity2; 351 352 } 353 354 @Override 355 public String toString(){ 356 357 //int lA = ca1Length; 358 //int lB = ca2Length; 359 //int distance = lA + lB - 2 * getNrEQR(); 360 361 StringBuffer str = new StringBuffer(""); 362 str.append("EQR:"); 363 str.append(getNrEQR()); 364 365 str.append("\tLen1:"); 366 str.append(this.getCa1Length()); 367 str.append("\tLen2:"); 368 str.append(this.getCa2Length()); 369 str.append(String.format("\tscore: %.2f",this.getAlignScore())); 370 str.append("\t"); 371 if ( algorithmName.equalsIgnoreCase(CeMain.algorithmName) || algorithmName.equalsIgnoreCase(CeSideChainMain.algorithmName)){ 372 str.append("Z-score:"); 373 str.append(String.format("%.2f",this.getProbability())); 374 } else { 375 str.append("Probability:"); 376 str.append(String.format("%.2e",this.getProbability())); 377 } 378 str.append("\tRMSD:"); 379 str.append(String.format("%.2f",this.getTotalRmsdOpt())); 380 381 str.append("\tSeqID:"); 382 str.append(String.format("%.0f",getIdentity()*100)); 383 str.append("%\tSeqSim:"); 384 str.append(String.format("%.0f",getSimilarity()*100)); 385 str.append("%\tCov1:"); 386 str.append(this.getCoverage1()); 387 str.append("%\tCov2:"); 388 str.append(this.getCoverage2()); 389 str.append("%"); 390 391 if ( tmScore != -1) { 392 str.append("\ttmScore:"); 393 str.append(String.format("%.2f",tmScore)); 394 } 395 str.append(newline); 396 397 398 return str.toString(); 399 } 400 401 public boolean isSignificantResult(){ 402 if ( algorithmName.equalsIgnoreCase(CeMain.algorithmName) || algorithmName.equalsIgnoreCase(CeSideChainMain.algorithmName)){ 403 if (probability >= 3.5) 404 return true; 405 } else { 406 if (probability < 0.01) 407 return true; 408 } 409 return false; 410 } 411 412 413 414 415 private void init(){ 416 shortAlign = false; 417 afpChainLen = 0; 418 419 afpChainList = null; 420 afpChainTwiBin = null; 421 afpChainTwiList = null; 422 chainRmsd=0; 423 chainLen = misLen = gapLen = 0; 424 425 blockResSize = null; 426 blockScore = null; 427 blockGap = null; 428 optAln = null; 429 pdbAln = null; 430 optLen = null; 431 432 optRmsd = null; 433 434 block2Afp = new int[maxTra+1]; 435 blockSize = new int[maxTra+1]; 436 blockRmsd = new double[maxTra+1]; 437 blockScore = new double[maxTra+1]; 438 blockGap = new int[maxTra+1]; 439 440 blockResSize = new int[maxTra+1]; 441 442 afpSet = new ArrayList<AFP>(); 443 totalLenIni = totalLenOpt = 0; 444 totalRmsdIni = totalRmsdOpt = 0.0; 445 446 afpChainTwiNum = 0; 447 alignScore = 0; 448 alignScoreUpdate = 0; 449 conn = new Double(0); 450 dvar = new Double(0); 451 calculationTime = 0; 452 453 similarity = -1; 454 identity = -1; 455 myResultsEQR = -1; 456 myResultsSimilarity1 = -1; 457 myResultsSimilarity2 = -1; 458 version = "1.0"; 459 sequentialAlignment = true; 460 distanceMatrix = null; 461 tmScore = -1; 462 description2=null; 463 } 464 465 /** 466 * Resets properties which can be calculated on the fly 467 */ 468 private void invalidate() { 469 myResultsEQR = -1; 470 myResultsSimilarity1 = -1; 471 myResultsSimilarity2 = -1; 472 identity = -1; 473 similarity = -1; 474 } 475 476 /** used temporarily during XML serialization to track the PDB positions of the alignmnet 477 * 478 * @return String array 479 */ 480 public String[][][] getPdbAln() { 481 return pdbAln; 482 } 483 484 485 public void setPdbAln(String[][][] pdbAln) { 486 this.pdbAln = pdbAln; 487 } 488 489 490 public Double getConn() 491 { 492 return conn; 493 } 494 495 496 public void setConn(Double conn) 497 { 498 this.conn = conn; 499 } 500 501 502 public Double getDVar() 503 { 504 return dvar; 505 } 506 507 508 public void setDVar(Double dvar) 509 { 510 this.dvar = dvar; 511 } 512 513 514 /** get the maximum nr of Twists that are allowed... 515 * 516 * @return maxTra, the max nr of twists 517 */ 518 public int getMaxTra() 519 { 520 return maxTra; 521 } 522 523 /** 524 * Set the maximum number of Twists that are allowed... 525 * @param maxTra 526 */ 527 public void setMaxTra(int maxTra) 528 { 529 this.maxTra = maxTra; 530 } 531 532 533 public double getAlignScore() 534 { 535 return alignScore; 536 } 537 538 public void setAlignScore(double alignScore) 539 { 540 this.alignScore = alignScore; 541 } 542 543 public double getAlignScoreUpdate() 544 { 545 return alignScoreUpdate; 546 } 547 548 public void setAlignScoreUpdate(double alignScoreUpdate) 549 { 550 this.alignScoreUpdate = alignScoreUpdate; 551 } 552 553 public int getAfpChainTwiNum() 554 { 555 return afpChainTwiNum; 556 } 557 558 public void setAfpChainTwiNum(int afpChainTwiNum) 559 { 560 this.afpChainTwiNum = afpChainTwiNum; 561 } 562 563 public int getMinLen() 564 { 565 return minLen; 566 } 567 568 public void setMinLen(int minLen) 569 { 570 this.minLen = minLen; 571 } 572 573 574 575 /** 576 * Get the set of AFPs for this alignment. 577 * An AFP is a local ungapped alignment between the two peptides. 578 * 579 * AFPs are set before the final optimization step. To get the final 580 * alignment, look at the aligned pairs from {@link #getOptAln()}. 581 * 582 * @return The optimal set of AFPs 583 * @see #getOptAln() 584 */ 585 public List<AFP> getAfpSet() 586 { 587 return afpSet; 588 } 589 590 591 /** 592 * Set the set of AFPs for this alignment. 593 * An AFP is a local ungapped alignment between the two peptides. 594 * 595 * AFPs are set before the final optimization step. To get the final 596 * alignment, look at the aligned pairs from {@link #getOptAln()}. 597 */ 598 public void setAfpSet(List<AFP> afpSet) 599 { 600 this.afpSet = afpSet; 601 } 602 603 public int[][] getAfpIndex() 604 { 605 return afpIndex; 606 } 607 608 public void setAfpIndex(int[][] afpIndex) 609 { 610 this.afpIndex = afpIndex; 611 } 612 613 614 public int[][] getAfpAftIndex() 615 { 616 return afpAftIndex; 617 } 618 619 public void setAfpAftIndex(int[][] afpAftIndex) 620 { 621 this.afpAftIndex = afpAftIndex; 622 } 623 624 625 public int[][] getAfpBefIndex() 626 { 627 return afpBefIndex; 628 } 629 630 public void setAfpBefIndex(int[][] afpBefIndex) 631 { 632 this.afpBefIndex = afpBefIndex; 633 } 634 635 636 public Matrix getDisTable1() 637 { 638 return disTable1; 639 } 640 641 public void setDisTable1(Matrix disTable1) 642 { 643 this.disTable1 = disTable1; 644 } 645 646 647 public Matrix getDisTable2() 648 { 649 return disTable2; 650 } 651 652 public void setDisTable2(Matrix disTable2) 653 { 654 this.disTable2 = disTable2; 655 } 656 657 658 public int[] getTwi() 659 { 660 return twi; 661 } 662 663 public void setTwi(int[] twi) 664 { 665 this.twi = twi; 666 } 667 668 public int getAfpChainLen() 669 { 670 return afpChainLen; 671 } 672 673 public void setAfpChainLen(int afpChainLen) 674 { 675 this.afpChainLen = afpChainLen; 676 } 677 678 public int[] getAfpChainList() 679 { 680 return afpChainList; 681 } 682 683 public void setAfpChainList(int[] afpChainList) 684 { 685 this.afpChainList = afpChainList; 686 } 687 688 public double[] getAfpChainTwiBin() 689 { 690 return afpChainTwiBin; 691 } 692 693 public void setAfpChainTwiBin(double[] afpChainTwiBin) 694 { 695 this.afpChainTwiBin = afpChainTwiBin; 696 } 697 698 public double[] getAfpChainTwiList() 699 { 700 return afpChainTwiList; 701 } 702 703 public void setAfpChainTwiList(double[] afpChainTwiList) 704 { 705 this.afpChainTwiList = afpChainTwiList; 706 } 707 708 public double getChainRmsd() 709 { 710 return chainRmsd; 711 } 712 713 /** The RMSD of the chain of AFPs. Set during AFPCHainer.traceBack(); 714 * 715 * @param chainRmsd 716 */ 717 public void setChainRmsd(double chainRmsd) 718 { 719 this.chainRmsd = chainRmsd; 720 } 721 722 public int getChainLen() 723 { 724 return chainLen; 725 } 726 727 public void setChainLen(int chainLen) 728 { 729 this.chainLen = chainLen; 730 } 731 732 public int getMisLen() 733 { 734 return misLen; 735 } 736 737 public void setMisLen(int misLen) 738 { 739 this.misLen = misLen; 740 } 741 742 public int getGapLen() 743 { 744 return gapLen; 745 } 746 747 public void setGapLen(int gapLen) 748 { 749 this.gapLen = gapLen; 750 } 751 752 /** The number of blocks in the alignment 753 * 754 * @return the nr of blocks in alignment 755 */ 756 public int getBlockNum() 757 { 758 return blockNum; 759 } 760 761 public void setBlockNum(int blockNum) 762 { 763 this.blockNum = blockNum; 764 } 765 766 public int getBlockNumIni() 767 { 768 return blockNumIni; 769 } 770 771 public void setBlockNumIni(int blockNumIni) 772 { 773 this.blockNumIni = blockNumIni; 774 } 775 776 public int getBlockNumClu() 777 { 778 return blockNumClu; 779 } 780 781 public void setBlockNumClu(int blockNumClu) 782 { 783 this.blockNumClu = blockNumClu; 784 } 785 786 public int getBlockNumSpt() 787 { 788 return blockNumSpt; 789 } 790 791 public void setBlockNumSpt(int blockNumSpt) 792 { 793 this.blockNumSpt = blockNumSpt; 794 } 795 796 public double[] getBlockRmsd() 797 { 798 return blockRmsd; 799 } 800 801 public void setBlockRmsd(double[] blockRmsd) 802 { 803 this.blockRmsd = blockRmsd; 804 } 805 806 public int[] getBlock2Afp() 807 { 808 return block2Afp; 809 } 810 811 public void setBlock2Afp(int[] block2Afp) 812 { 813 this.block2Afp = block2Afp; 814 } 815 816 public int[] getBlockSize() 817 { 818 return blockSize; 819 } 820 821 public void setBlockSize(int[] blockSize) 822 { 823 this.blockSize = blockSize; 824 } 825 826 public double[] getBlockScore() 827 { 828 return blockScore; 829 } 830 831 public void setBlockScore(double[] blockScore) 832 { 833 this.blockScore = blockScore; 834 } 835 836 public int[] getBlockGap() 837 { 838 return blockGap; 839 } 840 841 public void setBlockGap(int[] blockGap) 842 { 843 this.blockGap = blockGap; 844 } 845 846 public int[] getBlockResSize() 847 { 848 return blockResSize; 849 } 850 851 public void setBlockResSize(int[] blockResSize) 852 { 853 this.blockResSize = blockResSize; 854 } 855 856 857 /** tracks the residues of the initial blocks (before optimization) 858 * 859 * 860 * @return list of block residues 861 */ 862 public int[][][] getBlockResList() 863 { 864 return blockResList; 865 } 866 867 public void setBlockResList(int[][][] blockResList) 868 { 869 this.blockResList = blockResList; 870 } 871 872 public int getFocusResn() 873 { 874 return focusResn; 875 } 876 877 public void setFocusResn(int focusResn) 878 { 879 this.focusResn = focusResn; 880 } 881 882 883 public int[] getFocusRes1() 884 { 885 return focusRes1; 886 } 887 888 public void setFocusRes1(int[] focusRes1) 889 { 890 this.focusRes1 = focusRes1; 891 } 892 893 894 public int[] getFocusRes2() 895 { 896 return focusRes2; 897 } 898 899 public void setFocusRes2(int[] focusRes2) 900 { 901 this.focusRes2 = focusRes2; 902 } 903 904 public int getFocusAfpn() 905 { 906 return focusAfpn; 907 } 908 909 public void setFocusAfpn(int focusAfpn) 910 { 911 this.focusAfpn = focusAfpn; 912 } 913 914 public int[] getFocusAfpList() 915 { 916 return focusAfpList; 917 } 918 919 public void setFocusAfpList(int[] focusAfpList) 920 { 921 this.focusAfpList = focusAfpList; 922 } 923 924 public boolean isShortAlign() 925 { 926 return shortAlign; 927 } 928 929 public void setShortAlign(boolean shortAlign) 930 { 931 this.shortAlign = shortAlign; 932 } 933 934 /** Tracks the Atom positions in the optimal alignment. Note: only considers the equivalent positions, gaps are ignored... 935 * first dimension is the block nr 936 * second dimension is 0 or 1 (the alignment chain index) 937 * third is the position 938 * @return int array 939 */ 940 public int[][][] getOptAln() 941 { 942 return optAln; 943 } 944 945 public void setOptAln(int[][][] optAln) 946 { 947 invalidate(); 948 this.optAln = optAln; 949 } 950 951 /** 952 * The length of each block 953 * @return lengths 954 */ 955 public int[] getOptLen() 956 { 957 return optLen; 958 } 959 960 public void setOptLen(int[] optLen) 961 { 962 this.optLen = optLen; 963 } 964 965 public double[] getOptRmsd() 966 { 967 return optRmsd; 968 } 969 970 public void setOptRmsd(double[] optRmsd) 971 { 972 this.optRmsd = optRmsd; 973 } 974 975 public int getOptLength() 976 { 977 return optLength; 978 } 979 980 /** The length of the optimal alignment. Set by AFPOptimizer.optimizeAln(). 981 * This should be the sum of the elements in optLen 982 * @param optLength 983 */ 984 public void setOptLength(int optLength) 985 { 986 this.optLength = optLength; 987 } 988 989 990 public char[] getAlnsymb() 991 { 992 return alnsymb; 993 } 994 995 public void setAlnsymb(char[] alnsymb) 996 { 997 this.alnsymb = alnsymb; 998 } 999 1000 1001 public char[] getAlnseq1() 1002 { 1003 return alnseq1; 1004 } 1005 1006 public void setAlnseq1(char[] alnseq1) 1007 { 1008 this.alnseq1 = alnseq1; 1009 } 1010 1011 1012 public char[] getAlnseq2() 1013 { 1014 return alnseq2; 1015 } 1016 1017 public void setAlnseq2(char[] alnseq2) 1018 { 1019 this.alnseq2 = alnseq2; 1020 } 1021 1022 1023 /** 1024 * @return The total length of the alignment, including gaps 1025 * @see #getOptLength(), the number of aligned residues in the final alignment. 1026 */ 1027 public int getAlnLength() 1028 { 1029 return alnLength; 1030 } 1031 1032 public void setAlnLength(int alnLength) 1033 { 1034 this.alnLength = alnLength; 1035 } 1036 1037 /** 1038 * @return The index of the first aligned residue in protein 1 1039 */ 1040 public int getAlnbeg1() 1041 { 1042 return alnbeg1; 1043 } 1044 1045 public void setAlnbeg1(int alnbeg1) 1046 { 1047 this.alnbeg1 = alnbeg1; 1048 } 1049 /** 1050 * @return The index of the first aligned residue in protein 2 1051 */ 1052 public int getAlnbeg2() 1053 { 1054 return alnbeg2; 1055 } 1056 1057 public void setAlnbeg2(int alnbeg2) 1058 { 1059 this.alnbeg2 = alnbeg2; 1060 } 1061 1062 public int getTotalLenIni() 1063 { 1064 return totalLenIni; 1065 } 1066 1067 public void setTotalLenIni(int totalLenIni) 1068 { 1069 this.totalLenIni = totalLenIni; 1070 } 1071 1072 public int getTotalLenOpt() 1073 { 1074 return totalLenOpt; 1075 } 1076 1077 public void setTotalLenOpt(int totalLenOpt) 1078 { 1079 this.totalLenOpt = totalLenOpt; 1080 } 1081 1082 /** this is the init-RMSD, not the final RMSD after refinement. 1083 * 1084 * @return totalRmsdIni 1085 */ 1086 public double getTotalRmsdIni() 1087 { 1088 return totalRmsdIni; 1089 } 1090 1091 /** this is the init-RMSD, not the final RMSD after refinement. 1092 * 1093 * @param totalRmsdIni 1094 */ 1095 public void setTotalRmsdIni(double totalRmsdIni) 1096 { 1097 this.totalRmsdIni = totalRmsdIni; 1098 } 1099 1100 1101 /** The RMSD of the final alignment. Use this to print overal alignment RMSD. 1102 * 1103 * @return total RMSD of the optimal alignment. 1104 */ 1105 public double getTotalRmsdOpt() 1106 { 1107 return totalRmsdOpt; 1108 } 1109 1110 /** The RMSD of the final alignment. Use this to print overal alignment RMSD. 1111 * 1112 * @param totalRmsdOpt : total RMSD of the optimal alignment 1113 */ 1114 public void setTotalRmsdOpt(double totalRmsdOpt) 1115 { 1116 this.totalRmsdOpt = totalRmsdOpt; 1117 } 1118 1119 1120 public String getName1() 1121 { 1122 return name1; 1123 } 1124 1125 1126 public void setName1(String name1) 1127 { 1128 this.name1 = name1; 1129 } 1130 1131 1132 1133 public String getName2() 1134 { 1135 return name2; 1136 } 1137 1138 public void setName2(String name2) 1139 { 1140 this.name2 = name2; 1141 } 1142 1143 1144 public long getCalculationTime() 1145 { 1146 return calculationTime; 1147 } 1148 1149 public void setCalculationTime(long calculationTime) 1150 { 1151 this.calculationTime = calculationTime; 1152 } 1153 1154 public int getCa1Length() 1155 { 1156 return ca1Length; 1157 } 1158 1159 public void setCa1Length(int ca1Length) 1160 { 1161 this.ca1Length = ca1Length; 1162 } 1163 1164 public int getCa2Length() 1165 { 1166 return ca2Length; 1167 } 1168 1169 public void setCa2Length(int ca2Length) 1170 { 1171 this.ca2Length = ca2Length; 1172 } 1173 1174 public long getIoTime() 1175 { 1176 return ioTime; 1177 } 1178 1179 public void setIoTime(long ioTime) 1180 { 1181 this.ioTime = ioTime; 1182 } 1183 1184 /** The probability (FATCAT) or Z-score (CE) of the alignment. 1185 * 1186 * @return either the probability (FATCAT) or the Z-score (CE) of the alignment. 1187 */ 1188 public double getProbability() 1189 { 1190 return probability; 1191 } 1192 1193 public void setProbability(double probability) 1194 { 1195 this.probability = probability; 1196 } 1197 1198 /** The percent of residues that are sequence-identical in the alignment. 1199 * 1200 * @return a value between 0 and 1 1201 */ 1202 public double getIdentity() { 1203 if ( identity <= 0) { 1204 calcSimilarity(); 1205 } 1206 return identity; 1207 } 1208 1209 public void setIdentity(double identity) { 1210 1211 this.identity = identity; 1212 } 1213 1214 1215 /** Returns the similarity score for the alignment. This gives the percent of 1216 * sequence similar residues in the alignment. 1217 * 1218 * @return a double between 0 and 1 1219 */ 1220 public double getSimilarity() { 1221 if ( similarity < 0) 1222 calcSimilarity(); 1223 return similarity; 1224 } 1225 1226 public void setSimilarity(double similarity) { 1227 this.similarity = similarity; 1228 } 1229 1230 1231 public double getNormAlignScore() 1232 { 1233 return normAlignScore; 1234 } 1235 1236 public void setNormAlignScore(double normAlignScore) 1237 { 1238 this.normAlignScore = normAlignScore; 1239 } 1240 1241 public Matrix[] getBlockRotationMatrix() 1242 { 1243 return blockRotationMatrix; 1244 } 1245 1246 public void setBlockRotationMatrix(Matrix[] blockRotationMatrix) 1247 { 1248 this.blockRotationMatrix = blockRotationMatrix; 1249 } 1250 1251 public Atom[] getBlockShiftVector() 1252 { 1253 return blockShiftVector; 1254 } 1255 1256 public void setBlockShiftVector(Atom[] blockShiftVector) 1257 { 1258 this.blockShiftVector = blockShiftVector; 1259 } 1260 1261 public String getAlgorithmName() { 1262 return algorithmName; 1263 } 1264 1265 /** 1266 * Caution has to be made when changing the algorithmName of an AFPChain, 1267 * since downstream analysis methods (scores, display, etc) behave 1268 * differently if the alignment is flexible (created with FatCat). 1269 * 1270 * @param algorithmName 1271 */ 1272 public void setAlgorithmName(String algorithmName) { 1273 this.algorithmName = algorithmName; 1274 } 1275 1276 public String getVersion() { 1277 return version; 1278 } 1279 1280 public void setVersion(String version) { 1281 this.version = version; 1282 } 1283 1284 /** 1285 * Get whether this alignment has the normal topology, ie the residues 1286 * aligned in each block increase sequentially over the original protein. 1287 * 1288 * This will be false if a circular permutation was detected. 1289 * @return true if the alignment is sequential 1290 */ 1291 public boolean isSequentialAlignment() { 1292 return sequentialAlignment; 1293 } 1294 /** 1295 * Set whether this alignment has the normal topology, ie the residues 1296 * aligned in each block increase sequentially over the original protein. 1297 * 1298 * This will be false if a circular permutation was detected. 1299 */ 1300 public void setSequentialAlignment(boolean sequentialAlignment) { 1301 this.sequentialAlignment = sequentialAlignment; 1302 } 1303 1304 /** 1305 * A matrix with <i>ca1length</i> rows and <i>ca2length</i> columns. 1306 * For CE this is the distance matrix, but the exact interpretation is left 1307 * up to the alignment algorithm. 1308 * 1309 * <p>Note: 1310 * A {@link org.biojava.nbio.structure.gui.JMatrixPanel}, which is used in 1311 * the structure-gui package to display distance matrices, will display the 1312 * transpose of this matrix. Be sure to take that into account when debugging 1313 * visually. 1314 * 1315 * @return A matrix with dimensions ca1length x ca2length, or null 1316 */ 1317 public Matrix getDistanceMatrix() { 1318 return distanceMatrix; 1319 } 1320 1321 /** 1322 * A matrix with <i>ca1length</i> rows and <i>ca2length</i> columns. 1323 * For CE this is the distance matrix, but the exact interpretation is left 1324 * up to the alignment algorithm. 1325 * @param distanceMatrix A matrix with dimensions ca1length x ca2length 1326 */ 1327 public void setDistanceMatrix(Matrix distanceMatrix) { 1328 this.distanceMatrix = distanceMatrix; 1329 1330 //System.out.println("Setting distMatrix "+(distanceMatrix==null?"null":"not null")); 1331 } 1332 1333 1334 public void setTMScore(double tmScore){ 1335 this.tmScore = tmScore; 1336 } 1337 1338 /** Returns the tmScore of the alignment. If the score has not been calcualted yet, 1339 * returns -1. To calculate it call AFPChainScorer.getTMScore(afpChain, ca1, ca2); 1340 * 1341 * @return -1, if not calculated, or the TM-score, a score between 0 and 1 1342 */ 1343 public double getTMScore() 1344 { 1345 1346 return tmScore; 1347 } 1348 1349 1350 1351 /** Get a textual description for the protein 2 of the alignment. 1352 * 1353 * @return 1354 */ 1355 public String getDescription2() { 1356 return description2; 1357 } 1358 1359 1360 /** Set the textual description for protein 2. 1361 * 1362 * @param desc 1363 */ 1364 public void setDescription2(String desc){ 1365 this.description2 = desc; 1366 } 1367 1368 1369 /* (non-Javadoc) 1370 * @see java.lang.Object#hashCode() 1371 */ 1372 @Override 1373 public int hashCode() { 1374 final int prime = 31; 1375 int result = 1; 1376 result = prime * result + blockNum; 1377 result = prime * result + ca1Length; 1378 result = prime * result + ca2Length; 1379 result = prime * result + Arrays.hashCode(optAln); 1380 result = prime * result + Arrays.hashCode(optLen); 1381 result = prime * result + optLength; 1382 return result; 1383 } 1384 1385 /** 1386 * A week equality metric. 1387 * 1388 * Checks if the optAlign is the same, and if the objects being compared 1389 * seem to be the same (same names, lengths). Does not check properties 1390 * of the alignment such as scores or superposition matrices. 1391 * @see java.lang.Object#equals(java.lang.Object) 1392 */ 1393 @Override 1394 public boolean equals(Object obj) { 1395 if (this == obj) 1396 return true; 1397 if (obj == null) 1398 return false; 1399 if (getClass() != obj.getClass()) 1400 return false; 1401 AFPChain other = (AFPChain) obj; 1402 if (blockNum != other.blockNum) 1403 return false; 1404 if (ca1Length != other.ca1Length) 1405 return false; 1406 if (ca2Length != other.ca2Length) 1407 return false; 1408 if (!Arrays.deepEquals(optAln, other.optAln)) 1409 return false; 1410 if (!Arrays.equals(optLen, other.optLen)) 1411 return false; 1412 if (optLength != other.optLength) 1413 return false; 1414 return true; 1415 } 1416 1417 1418}