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 */ 021package org.biojava.nbio.structure.secstruc; 022 023import org.biojava.nbio.structure.Atom; 024import org.biojava.nbio.structure.Group; 025import org.biojava.nbio.structure.StructureTools; 026import org.slf4j.Logger; 027import org.slf4j.LoggerFactory; 028 029/** 030 * This class extends the basic container for secondary structure annotation, 031 * including all the information used in the DSSP algorithm. 032 * 033 * @author Andreas Prlic 034 * @author Aleix Lafita 035 * 036 */ 037public class SecStrucState extends SecStrucInfo { 038 039 private static final Logger logger = LoggerFactory 040 .getLogger(SecStrucState.class); 041 042 private double phi; 043 private double psi; 044 private double omega; 045 private float kappa; 046 047 private HBond accept1; // from CO of partner to NH of this 048 private HBond accept2; // this is the donor of accept partner 049 private HBond donor1; // from CO of this to NH of partner 050 private HBond donor2; // this is the acceptor of donor partner 051 052 // Symbols: starting '>', ending '<', or both 'X'. 053 // Number means bracketed n-turn residue without h-bond 054 private char[] turn; 055 private boolean bend; 056 057 private BetaBridge bridge1; 058 private BetaBridge bridge2; 059 060 public SecStrucState(Group g, String ass, SecStrucType t) { 061 super(g, ass, t); 062 063 phi = 360; 064 psi = 360; 065 omega = 360; 066 067 accept1 = new HBond(); 068 accept2 = new HBond(); 069 donor1 = new HBond(); 070 donor2 = new HBond(); 071 072 bridge1 = null; 073 bridge2 = null; 074 075 turn = new char[3]; 076 turn[0] = ' '; 077 turn[1] = ' '; 078 turn[2] = ' '; 079 080 bend = false; 081 kappa = 360; 082 } 083 084 public boolean isBend() { 085 return bend; 086 } 087 088 public void setBend(boolean bend) { 089 this.bend = bend; 090 } 091 092 public float getKappa() { 093 return kappa; 094 } 095 096 public void setKappa(float kappa) { 097 this.kappa = kappa; 098 } 099 100 public char[] getTurn() { 101 return turn; 102 } 103 104 /** 105 * Set the turn column corresponding to 3,4 or 5 helix patterns. If starting 106 * > or ending < was set and the opposite is being set, the value will be 107 * converted to X. If a number was set, it will be overwritten by the new 108 * character. 109 * 110 * @param c 111 * character in the column 112 * @param t 113 * turn of the helix {3,4,5} 114 */ 115 public void setTurn(char c, int t) { 116 if (turn[t - 3] == 'X') 117 return; 118 else if (turn[t - 3] == '<' && c == '>' || turn[t - 3] == '>' 119 && c == '<') { 120 turn[t - 3] = 'X'; 121 } else if (turn[t - 3] == '<' || turn[t - 3] == '>') 122 return; 123 else 124 turn[t - 3] = c; 125 } 126 127 public HBond getAccept1() { 128 return accept1; 129 } 130 131 public void setAccept1(HBond accept1) { 132 this.accept1 = accept1; 133 } 134 135 public HBond getAccept2() { 136 return accept2; 137 } 138 139 public void setAccept2(HBond accept2) { 140 this.accept2 = accept2; 141 } 142 143 public HBond getDonor1() { 144 return donor1; 145 } 146 147 public void setDonor1(HBond donor1) { 148 this.donor1 = donor1; 149 } 150 151 public HBond getDonor2() { 152 return donor2; 153 } 154 155 public void setDonor2(HBond donor2) { 156 this.donor2 = donor2; 157 } 158 159 public double getPhi() { 160 return phi; 161 } 162 163 public void setPhi(double phi) { 164 this.phi = phi; 165 } 166 167 public double getPsi() { 168 return psi; 169 } 170 171 public void setPsi(double psi) { 172 this.psi = psi; 173 } 174 175 public double getOmega() { 176 return omega; 177 } 178 179 public void setOmega(double omega) { 180 this.omega = omega; 181 } 182 183 public BetaBridge getBridge1() { 184 return bridge1; 185 } 186 187 public BetaBridge getBridge2() { 188 return bridge2; 189 } 190 191 /** 192 * Adds a Bridge to the residue. Each residue can only store two bridges. If 193 * the residue contains already two Bridges, the Bridge will not be added 194 * and the method returns false. 195 * 196 * @param bridge 197 * @return false if the Bridge was not added, true otherwise 198 */ 199 public boolean addBridge(BetaBridge bridge) { 200 if (bridge1 == null) { 201 bridge1 = bridge; 202 return true; 203 } else if (bridge1.equals(bridge)) { 204 return true; 205 } else if (bridge2 == null) { 206 bridge2 = bridge; 207 return true; 208 } else if (bridge2.equals(bridge)) { 209 return true; 210 } else { //no space left, cannot add the bridge 211 logger.info("Residue forms more than 2 beta Bridges, " 212 + "DSSP output might differ in Bridges column."); 213 return false; 214 } 215 } 216 217 public void setBridge1(BetaBridge bridge1) { 218 this.bridge1 = bridge1; 219 } 220 221 public void setBridge2(BetaBridge bridge2) { 222 this.bridge2 = bridge2; 223 } 224 225 public String printDSSPline(int index) { 226 227 StringBuffer buf = new StringBuffer(); 228 229 // # 230 if (index < 9) 231 buf.append(" "); 232 else if (index < 99) 233 buf.append(" "); 234 else if (index < 999) 235 buf.append(" "); 236 else 237 buf.append(" "); 238 buf.append(index + 1); 239 240 // RESIDUE 241 int resnum = parent.getResidueNumber().getSeqNum(); 242 if (resnum < 10) 243 buf.append(" "); 244 else if (resnum < 100) 245 buf.append(" "); 246 else 247 buf.append(" "); 248 buf.append(resnum); 249 Character insCode = parent.getResidueNumber().getInsCode(); 250 if (insCode != null) 251 buf.append(insCode); 252 else 253 buf.append(" "); 254 buf.append(parent.getChainId()); 255 if (parent.getChainId().length() == 1) 256 buf.append(" "); 257 258 // AA 259 char aaLetter = StructureTools.get1LetterCode(parent.getPDBName()); 260 buf.append(aaLetter + " "); 261 262 // STRUCTURE 263 buf.append(type).append(" "); 264 265 for (int t = 0; t < 3; t++) { 266 buf.append(turn[t]); 267 } 268 269 buf.append(" "); 270 271 if (isBend()) 272 buf.append('S'); 273 else 274 buf.append(" "); 275 276 buf.append(" "); 277 278 int bp1 = 0; 279 if (bridge1 != null) { 280 if (bridge1.partner1 != index) 281 bp1 = bridge1.partner1 + 1; 282 else 283 bp1 = bridge1.partner2 + 1; 284 } 285 // TODO a clever way to do this? 286 if (bp1 < 10) 287 buf.append(" " + bp1); 288 else if (bp1 < 100) 289 buf.append(" " + bp1); 290 else if (bp1 < 1000) 291 buf.append(" " + bp1); 292 else 293 buf.append(bp1); 294 295 int bp2 = 0; 296 if (bridge2 != null) { 297 if (bridge2.partner1 != index) 298 bp2 = bridge2.partner1 + 1; 299 else 300 bp2 = bridge2.partner2 + 1; 301 } 302 if (bp2 < 10) 303 buf.append(" " + bp2); 304 else if (bp2 < 100) 305 buf.append(" " + bp2); 306 else if (bp2 < 1000) 307 buf.append(" " + bp2); 308 else 309 buf.append(bp2); 310 311 // beta-sheet label TODO 312 buf.append(" "); 313 314 // ACC TODO 315 buf.append(" "); 316 317 // N-H-->O 318 int p1 = accept1.getPartner(); 319 double e1 = (accept1.getEnergy() / 1000.0); 320 if (e1 < 0.0) 321 p1 -= index; 322 buf.append(String.format("%6d,%4.1f", p1, e1)); 323 324 // O-->H-N 325 int p2 = donor1.getPartner(); 326 double e2 = (donor1.getEnergy() / 1000.0); 327 if (e2 < 0.0) 328 p2 -= index; 329 buf.append(String.format("%6d,%4.1f", p2, e2)); 330 331 // N-H-->O 332 int p3 = accept2.getPartner(); 333 double e3 = (accept2.getEnergy() / 1000.0); 334 if (e3 < 0.0) 335 p3 -= index; 336 buf.append(String.format("%6d,%4.1f", p3, e3)); 337 338 // O-->H-N 339 int p4 = donor2.getPartner(); 340 double e4 = (donor2.getEnergy() / 1000.0); 341 if (e4 < 0.0) 342 p4 -= index; 343 buf.append(String.format("%6d,%4.1f", p4, e4)); 344 345 // TCO TODO 346 buf.append(" "); 347 348 // KAPPA 349 buf.append(String.format("%6.1f", kappa)); 350 351 // ALPHA TODO 352 buf.append(" "); 353 354 // PHI PSI 355 buf.append(String.format("%6.1f %6.1f ", phi, psi)); 356 357 // X-CA Y-CA Z-CA 358 Atom ca = parent.getAtom("CA"); 359 buf.append(String.format("%6.1f %6.1f %6.1f", ca.getX(), ca.getY(), 360 ca.getZ())); 361 362 return buf.toString(); 363 } 364 365}