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/** 044 * A class that does calculations on an AFPChain 045 * 046 * @author Andreas Prlic 047 * 048 */ 049public class FatCatAligner 050{ 051 052 public static final boolean debug = false; 053 public static final boolean printTimeStamps = false; 054 055 AFPChain afpChain ; 056 Group[] twistedGroups; 057 058 059 060 public AFPChain getAfpChain() 061 { 062 return afpChain; 063 } 064 065 066 public Group[] getTwistedGroups() 067 { 068 069 return twistedGroups; 070 } 071 072 public void setTwistedGroups(Group[] twistedGroups) 073 { 074 this.twistedGroups = twistedGroups; 075 } 076 077 078 public void align(Atom[] ca1, Atom[] ca2, boolean doRigid, FatCatParameters params) throws StructureException{ 079 080 long tstart = System.currentTimeMillis(); 081 082 afpChain = new AFPChain(FatCat.algorithmName); 083 afpChain.setCa1Length(ca1.length); 084 afpChain.setCa2Length(ca2.length); 085 086 087 088 AFPCalculator.extractAFPChains(params, afpChain,ca1, ca2); 089 090 long cend = System.currentTimeMillis(); 091 092 if (printTimeStamps) 093 System.out.println("calculation took:" + (cend - tstart) + " ms."); 094 095 096 AFPCalculator.sortAfps(afpChain,ca1,ca2); 097 098 if ( printTimeStamps) { 099 long send = System.currentTimeMillis(); 100 101 102 System.out.println("sorting took:" + (send - cend) + " ms."); 103 } 104 105 if ( doRigid) 106 this.twistedGroups = rChainAfp(params, afpChain,ca1,ca2); 107 108 else { 109 this.twistedGroups = chainAfp(params,afpChain,ca1,ca2); 110 } 111 112 // long start = System.currentTimeMillis(); 113 long end = System.currentTimeMillis(); 114 afpChain.setCalculationTime(end-tstart); 115 if ( printTimeStamps) 116 System.out.println("TOTAL calc time: " + (end -tstart) / 1000.0); 117 118 } 119 120 121 122 123 /** runs rigid chaining process 124 * 125 */ 126 private static Group[] rChainAfp(FatCatParameters params, AFPChain afpChain, Atom[] ca1, Atom[] ca2) throws StructureException{ 127 params.setMaxTra(0); 128 afpChain.setMaxTra(0); 129 return chainAfp(params,afpChain,ca1,ca2); 130 } 131 132 /** 133 * run AFP chaining allowing up to maxTra flexible regions. 134 * Input is original coordinates. 135 * 136 */ 137 private static Group[] chainAfp(FatCatParameters params,AFPChain afpChain, Atom[] ca1, Atom[] ca2) throws StructureException{ 138 139 // we don;t want to rotate input atoms, do we? 140 Atom[] ca2clone = StructureTools.cloneAtomArray(ca2); 141 142 List<AFP> afpSet = afpChain.getAfpSet(); 143 144 if (debug) 145 System.out.println("entering chainAfp"); 146 int afpNum = afpSet.size(); 147 148 if ( afpNum < 1) 149 return new Group[0]; 150 151 long bgtime = System.currentTimeMillis(); 152 if(debug) { 153 System.out.println(String.format("total AFP %d\n", afpNum)); 154 } 155 156 //run AFP chaining 157 158 AFPChainer.doChainAfp(params,afpChain ,ca1,ca2); 159 160 int afpChainLen = afpChain.getAfpChainLen(); 161 162 if(afpChainLen < 1) { 163 164 afpChain.setShortAlign(true); 165 return new Group[0]; 166 } //very short alignment 167 168 long chaintime = System.currentTimeMillis(); 169 if(debug) { 170 171 System.out.println("Afp chaining: time " + (chaintime-bgtime)); 172 } 173 174 // do post processing 175 176 AFPPostProcessor.postProcess(params, afpChain,ca1,ca2); 177 178 // Optimize the final alignment 179 180 AFPOptimizer.optimizeAln(params, afpChain,ca1,ca2); 181 182 AFPOptimizer.blockInfo( afpChain); 183 184 AFPOptimizer.updateScore(params,afpChain); 185 186 AFPAlignmentDisplay.getAlign(afpChain,ca1,ca2); 187 188 Group[] twistedPDB = AFPTwister.twistPDB(afpChain, ca1, ca2clone); 189 190 SigEva sig = new SigEva(); 191 double probability = sig.calSigAll(params, afpChain); 192 afpChain.setProbability(probability); 193 double normAlignScore = sig.calNS(params,afpChain); 194 afpChain.setNormAlignScore(normAlignScore); 195 double tmScore = AFPChainScorer.getTMScore(afpChain, ca1, ca2,false); 196 afpChain.setTMScore(tmScore); 197 198 /* 199 200 SIGEVA sig; 201 probability = sig.calSigAll(maxTra, sparse, pro1Len, pro2Len, alignScore, totalRmsdOpt, optLength, blockNum - 1); 202 normAlignScore = sig.calNS(pro1Len, pro2Len, alignScore, totalRmsdOpt, optLength, blockNum - 1); 203 204 */ 205 206 //if(maxTra == 0) probability = sig.calSigRigid(pro1Len, pro2Len, alignScore, totalRmsdOpt, optLength); 207 //else probability = sig.calSigFlexi(pro1Len, pro2Len, alignScore, totalRmsdOpt, optLength, blockNum - 1); 208 209 if(debug) { 210 211 long nowtime = System.currentTimeMillis(); 212 long diff = nowtime - chaintime; 213 System.out.println("Alignment optimization: time "+ diff); 214 215 System.out.println("score: " + afpChain.getAlignScore()); 216 System.out.println("opt length: " + afpChain.getOptLength()); 217 System.out.println("opt rmsd: "+ afpChain.getTotalRmsdOpt()); 218 219 } 220 return twistedPDB; 221 222 } 223 224}