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