/* * BioJava development code * * This code may be freely distributed and modified under the * terms of the GNU Lesser General Public Licence. This should * be distributed with the code. If you do not have a copy, * see: * * http://www.gnu.org/copyleft/lesser.html * * Copyright for this code is held jointly by the individual * authors. These should be listed in @author doc comments. * * For more information on the BioJava project and its aims, * or to join the biojava-l mailing list, visit the home page * at: * * http://www.biojava.org/ * */ package org.biojava.nbio.structure.secstruc; import org.biojava.nbio.structure.Atom; import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.StructureTools; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This class extends the basic container for secondary structure annotation, * including all the information used in the DSSP algorithm. * * @author Andreas Prlic * @author Aleix Lafita * */ public class SecStrucState extends SecStrucInfo { private static final Logger logger = LoggerFactory .getLogger(SecStrucState.class); private double phi; private double psi; private double omega; private float kappa; private HBond accept1; // from CO of partner to NH of this private HBond accept2; // this is the donor of accept partner private HBond donor1; // from CO of this to NH of partner private HBond donor2; // this is the acceptor of donor partner // Symbols: starting '>', ending '<', or both 'X'. // Number means bracketed n-turn residue without h-bond private char[] turn; private boolean bend; private BetaBridge bridge1; private BetaBridge bridge2; public SecStrucState(Group g, String ass, SecStrucType t) { super(g, ass, t); phi = 360; psi = 360; omega = 360; accept1 = new HBond(); accept2 = new HBond(); donor1 = new HBond(); donor2 = new HBond(); bridge1 = null; bridge2 = null; turn = new char[3]; turn[0] = ' '; turn[1] = ' '; turn[2] = ' '; bend = false; kappa = 360; } public boolean isBend() { return bend; } public void setBend(boolean bend) { this.bend = bend; } public float getKappa() { return kappa; } public void setKappa(float kappa) { this.kappa = kappa; } public char[] getTurn() { return turn; } /** * Set the turn column corresponding to 3,4 or 5 helix patterns. If starting * > or ending < was set and the opposite is being set, the value will be * converted to X. If a number was set, it will be overwritten by the new * character. * * @param c * character in the column * @param t * turn of the helix {3,4,5} */ public void setTurn(char c, int t) { if (turn[t - 3] == 'X') return; else if (turn[t - 3] == '<' && c == '>' || turn[t - 3] == '>' && c == '<') { turn[t - 3] = 'X'; } else if (turn[t - 3] == '<' || turn[t - 3] == '>') return; else turn[t - 3] = c; } public HBond getAccept1() { return accept1; } public void setAccept1(HBond accept1) { this.accept1 = accept1; } public HBond getAccept2() { return accept2; } public void setAccept2(HBond accept2) { this.accept2 = accept2; } public HBond getDonor1() { return donor1; } public void setDonor1(HBond donor1) { this.donor1 = donor1; } public HBond getDonor2() { return donor2; } public void setDonor2(HBond donor2) { this.donor2 = donor2; } public double getPhi() { return phi; } public void setPhi(double phi) { this.phi = phi; } public double getPsi() { return psi; } public void setPsi(double psi) { this.psi = psi; } public double getOmega() { return omega; } public void setOmega(double omega) { this.omega = omega; } public BetaBridge getBridge1() { return bridge1; } public BetaBridge getBridge2() { return bridge2; } /** * Adds a Bridge to the residue. Each residue can only store two bridges. If * the residue contains already two Bridges, the Bridge will not be added * and the method returns false. * * @param bridge * @return false if the Bridge was not added, true otherwise */ public boolean addBridge(BetaBridge bridge) { if (bridge1 == null) { bridge1 = bridge; return true; } else if (bridge1.equals(bridge)) { return true; } else if (bridge2 == null) { bridge2 = bridge; return true; } else if (bridge2.equals(bridge)) { return true; } else { //no space left, cannot add the bridge logger.info("Residue forms more than 2 beta Bridges, " + "DSSP output might differ in Bridges column."); return false; } } public void setBridge1(BetaBridge bridge1) { this.bridge1 = bridge1; } public void setBridge2(BetaBridge bridge2) { this.bridge2 = bridge2; } public String printDSSPline(int index) { StringBuffer buf = new StringBuffer(); // # if (index < 9) buf.append(" "); else if (index < 99) buf.append(" "); else if (index < 999) buf.append(" "); else buf.append(" "); buf.append(index + 1); // RESIDUE int resnum = parent.getResidueNumber().getSeqNum(); if (resnum < 10) buf.append(" "); else if (resnum < 100) buf.append(" "); else buf.append(" "); buf.append(resnum); Character insCode = parent.getResidueNumber().getInsCode(); if (insCode != null) buf.append(insCode); else buf.append(" "); buf.append(parent.getChainId()); if (parent.getChainId().length() == 1) buf.append(" "); // AA char aaLetter = StructureTools.get1LetterCode(parent.getPDBName()); buf.append(aaLetter).append(" "); // STRUCTURE buf.append(type).append(" "); for (int t = 0; t < 3; t++) { buf.append(turn[t]); } buf.append(" "); if (isBend()) buf.append('S'); else buf.append(" "); buf.append(" "); int bp1 = 0; if (bridge1 != null) { if (bridge1.partner1 != index) bp1 = bridge1.partner1 + 1; else bp1 = bridge1.partner2 + 1; } // TODO a clever way to do this? if (bp1 < 10) buf.append(" ").append(bp1); else if (bp1 < 100) buf.append(" ").append(bp1); else if (bp1 < 1000) buf.append(" ").append(bp1); else buf.append(bp1); int bp2 = 0; if (bridge2 != null) { if (bridge2.partner1 != index) bp2 = bridge2.partner1 + 1; else bp2 = bridge2.partner2 + 1; } if (bp2 < 10) buf.append(" ").append(bp2); else if (bp2 < 100) buf.append(" ").append(bp2); else if (bp2 < 1000) buf.append(" ").append(bp2); else buf.append(bp2); // beta-sheet label TODO buf.append(" "); // ACC TODO buf.append(" "); // N-H-->O int p1 = accept1.getPartner(); double e1 = (accept1.getEnergy() / 1000.0); if (e1 < 0.0) p1 -= index; buf.append(String.format("%6d,%4.1f", p1, e1)); // O-->H-N int p2 = donor1.getPartner(); double e2 = (donor1.getEnergy() / 1000.0); if (e2 < 0.0) p2 -= index; buf.append(String.format("%6d,%4.1f", p2, e2)); // N-H-->O int p3 = accept2.getPartner(); double e3 = (accept2.getEnergy() / 1000.0); if (e3 < 0.0) p3 -= index; buf.append(String.format("%6d,%4.1f", p3, e3)); // O-->H-N int p4 = donor2.getPartner(); double e4 = (donor2.getEnergy() / 1000.0); if (e4 < 0.0) p4 -= index; buf.append(String.format("%6d,%4.1f", p4, e4)); // TCO TODO buf.append(" "); // KAPPA buf.append(String.format("%6.1f", kappa)); // ALPHA TODO buf.append(" "); // PHI PSI buf.append(String.format("%6.1f %6.1f ", phi, psi)); // X-CA Y-CA Z-CA Atom ca = parent.getAtom("CA"); buf.append(String.format("%6.1f %6.1f %6.1f", ca.getX(), ca.getY(), ca.getZ())); return buf.toString(); } }