001/* This class is based on the original FATCAT implementation by 002 * <pre> 003 * Yuzhen Ye & Adam Godzik (2003) 004 * Flexible structure alignment by chaining aligned fragment pairs allowing twists. 005 * Bioinformatics vol.19 suppl. 2. ii246-ii255. 006 * https://www.ncbi.nlm.nih.gov/pubmed/14534198 007 * </pre> 008 * 009 * Thanks to Yuzhen Ye and A. Godzik for granting permission to freely use and redistribute this code. 010 * 011 * This code may be freely distributed and modified under the 012 * terms of the GNU Lesser General Public Licence. This should 013 * be distributed with the code. If you do not have a copy, 014 * see: 015 * 016 * http://www.gnu.org/copyleft/lesser.html 017 * 018 * Copyright for this code is held jointly by the individual 019 * authors. These should be listed in @author doc comments. 020 * 021 * 022 * Created on Jun 17, 2009 023 * Created by Andreas Prlic - RCSB PDB 024 * 025 */ 026 027package org.biojava.nbio.structure.align.fatcat.calc; 028 029import org.biojava.nbio.structure.Atom; 030import org.biojava.nbio.structure.Group; 031import org.biojava.nbio.structure.StructureException; 032import org.biojava.nbio.structure.StructureTools; 033import org.biojava.nbio.structure.align.AFPTwister; 034import org.biojava.nbio.structure.align.fatcat.FatCat; 035import org.biojava.nbio.structure.align.model.AFP; 036import org.biojava.nbio.structure.align.model.AFPChain; 037import org.biojava.nbio.structure.align.util.AFPAlignmentDisplay; 038import org.biojava.nbio.structure.align.util.AFPChainScorer; 039 040import java.util.List; 041 042 043/** A class that does calculations on an AFPChain 044 * 045 * @author Andreas Prlic 046 * 047 */ 048public class FatCatAligner 049{ 050 051 public static final boolean debug = false; 052 public static final boolean printTimeStamps = false; 053 054 AFPChain afpChain ; 055 Group[] twistedGroups; 056 057 058 059 public AFPChain getAfpChain() 060 { 061 return afpChain; 062 } 063 064 065 public Group[] getTwistedGroups() 066 { 067 068 return twistedGroups; 069 } 070 071 public void setTwistedGroups(Group[] twistedGroups) 072 { 073 this.twistedGroups = twistedGroups; 074 } 075 076 077 public void align(Atom[] ca1, Atom[] ca2, boolean doRigid, FatCatParameters params) throws StructureException{ 078 079 long tstart = System.currentTimeMillis(); 080 081 afpChain = new AFPChain(FatCat.algorithmName); 082 afpChain.setCa1Length(ca1.length); 083 afpChain.setCa2Length(ca2.length); 084 085 086 087 AFPCalculator.extractAFPChains(params, afpChain,ca1, ca2); 088 089 long cend = System.currentTimeMillis(); 090 091 if (printTimeStamps) 092 System.out.println("calculation took:" + (cend - tstart) + " ms."); 093 094 095 AFPCalculator.sortAfps(afpChain,ca1,ca2); 096 097 if ( printTimeStamps) { 098 long send = System.currentTimeMillis(); 099 100 101 System.out.println("sorting took:" + (send - cend) + " ms."); 102 } 103 104 if ( doRigid) 105 this.twistedGroups = rChainAfp(params, afpChain,ca1,ca2); 106 107 else { 108 this.twistedGroups = chainAfp(params,afpChain,ca1,ca2); 109 } 110 111 // long start = System.currentTimeMillis(); 112 long end = System.currentTimeMillis(); 113 afpChain.setCalculationTime(end-tstart); 114 if ( printTimeStamps) 115 System.out.println("TOTAL calc time: " + (end -tstart) / 1000.0); 116 117 } 118 119 120 121 122 /** runs rigid chaining process 123 * 124 */ 125 private static Group[] rChainAfp(FatCatParameters params, AFPChain afpChain, Atom[] ca1, Atom[] ca2) throws StructureException{ 126 params.setMaxTra(0); 127 afpChain.setMaxTra(0); 128 return chainAfp(params,afpChain,ca1,ca2); 129 } 130 131 /** 132 * run AFP chaining allowing up to maxTra flexible regions. 133 * Input is original coordinates. 134 * 135 */ 136 private static Group[] chainAfp(FatCatParameters params,AFPChain afpChain, Atom[] ca1, Atom[] ca2) throws StructureException{ 137 138 // we don;t want to rotate input atoms, do we? 139 Atom[] ca2clone = StructureTools.cloneAtomArray(ca2); 140 141 List<AFP> afpSet = afpChain.getAfpSet(); 142 143 if (debug) 144 System.out.println("entering chainAfp"); 145 int afpNum = afpSet.size(); 146 147 if ( afpNum < 1) 148 return new Group[0]; 149 150 long bgtime = System.currentTimeMillis(); 151 if(debug) { 152 System.out.println(String.format("total AFP %d\n", afpNum)); 153 } 154 155 //run AFP chaining 156 157 AFPChainer.doChainAfp(params,afpChain ,ca1,ca2); 158 159 int afpChainLen = afpChain.getAfpChainLen(); 160 161 if(afpChainLen < 1) { 162 163 afpChain.setShortAlign(true); 164 return new Group[0]; 165 } //very short alignment 166 167 long chaintime = System.currentTimeMillis(); 168 if(debug) { 169 170 System.out.println("Afp chaining: time " + (chaintime-bgtime)); 171 } 172 173 // do post processing 174 175 AFPPostProcessor.postProcess(params, afpChain,ca1,ca2); 176 177 // Optimize the final alignment 178 179 AFPOptimizer.optimizeAln(params, afpChain,ca1,ca2); 180 181 AFPOptimizer.blockInfo( afpChain); 182 183 AFPOptimizer.updateScore(params,afpChain); 184 185 AFPAlignmentDisplay.getAlign(afpChain,ca1,ca2); 186 187 Group[] twistedPDB = AFPTwister.twistPDB(afpChain, ca1, ca2clone); 188 189 SigEva sig = new SigEva(); 190 double probability = sig.calSigAll(params, afpChain); 191 afpChain.setProbability(probability); 192 double normAlignScore = sig.calNS(params,afpChain); 193 afpChain.setNormAlignScore(normAlignScore); 194 double tmScore = AFPChainScorer.getTMScore(afpChain, ca1, ca2,false); 195 afpChain.setTMScore(tmScore); 196 197 /* 198 199 SIGEVA sig; 200 probability = sig.calSigAll(maxTra, sparse, pro1Len, pro2Len, alignScore, totalRmsdOpt, optLength, blockNum - 1); 201 normAlignScore = sig.calNS(pro1Len, pro2Len, alignScore, totalRmsdOpt, optLength, blockNum - 1); 202 203 */ 204 205 //if(maxTra == 0) probability = sig.calSigRigid(pro1Len, pro2Len, alignScore, totalRmsdOpt, optLength); 206 //else probability = sig.calSigFlexi(pro1Len, pro2Len, alignScore, totalRmsdOpt, optLength, blockNum - 1); 207 208 if(debug) { 209 210 long nowtime = System.currentTimeMillis(); 211 long diff = nowtime - chaintime; 212 System.out.println("Alignment optimization: time "+ diff); 213 214 System.out.println("score: " + afpChain.getAlignScore()); 215 System.out.println("opt length: " + afpChain.getOptLength()); 216 System.out.println("opt rmsd: "+ afpChain.getTotalRmsdOpt()); 217 218 } 219 return twistedPDB; 220 221 } 222 223}