/* * This file is part of MoleculeViewer. * * MoleculeViewer is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MoleculeViewer is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with MoleculeViewer. If not, see <http://www.gnu.org/licenses/>. */ package astex; /* Copyright Astex Technology Ltd. 1999 */ /* Copyright David Hall, Boston University, 2011 */ /* * 08-11-99 mjh * created */ import astex.generic.*; import java.awt.Color; import java.util.*; /** * A class for storing a group of atoms that form part * of a protein residue. */ public class Residue extends Generic implements Selectable { /** Default constructor. */ public Residue(){ set(ResidueColor, Color.white); set(Torsions, Boolean.FALSE); set(TorsionRadius, Double.valueOf(0.4)); set(TorsionGreek, Boolean.TRUE); set(TorsionFormat, "<3d=true,size=0.3>%t %.1f"); } /** Dynamic array of atoms. */ private List<Atom> atoms = new ArrayList<Atom>(6); /** Undefined residue number. */ public static final int undefinedResidueNumber = -9999; /** Undefined residue name. */ private static final String undefinedResidueName = "XXX"; /** Parent chain. */ private Chain parent = null; /** Set the parent chain. */ public void setParent(Chain chain){ parent = chain; } /** Get the parent. */ public Chain getParent(){ return parent; } /** Insertion code. */ private char insertionCode = ' '; /** Set the insertion code. */ public void setInsertionCode(char code){ insertionCode = code; } /** Get the insertion code. */ public char getInsertionCode(){ return insertionCode; } /** Residue name. */ private String name = null; /** Set the residue name. */ public void setName(String newName){ name = newName; String colorName = Settings.getString("residue", name + ".color", "0x000000"); int c = Color32.getColorFromName(colorName); Color color = new Color(c); set(ResidueColor, color); } /** Get the residue name. */ public String getName(){ if(name == null) return undefinedResidueName; return name; } public enum SS { Undefined, Sheet, Helix, Helix310, Turn, Coil } /** The secondary structure type. */ private SS secondaryStructure = SS.Coil; /** * Get the value of secondaryStructure. * @return value of secondaryStructure. */ public SS getSecondaryStructure() { return secondaryStructure; } /** * Set the value of secondaryStructure. * @param v Value to assign to secondaryStructure. */ public void setSecondaryStructure(SS v) { this.secondaryStructure = v; } /** Residue number. */ private int number = undefinedResidueNumber; /** Sequential sequence number. */ private int sequentialNumber = undefinedResidueNumber; public void setSequentialNumber(int sNumber){ sequentialNumber = sNumber; } /** Set the residue number. */ public void setNumber(int newNumber){ number = newNumber; } /** Get the sequential residue number. */ public int getSequentialNumber(){ if(sequentialNumber == undefinedResidueNumber) return 1; return sequentialNumber; } /** Get the residue number. */ public int getNumber(){ if(number == undefinedResidueNumber) return 1; return number; } /** Add an atom to the list. */ public void addAtom(Atom atom){ atoms.add(atom); } /** Remove an atom from the residue. */ public void removeAtom(Atom atom){ atoms.remove(atom); if(atoms.isEmpty()){ Chain chain = getParent(); chain.removeResidue(this); } } /** * Return the number of atoms in the molecule. */ public int getAtomCount(){ return atoms.size(); } /** * Return the specified atom. */ public Atom getAtom(int index){ return atoms.get(index); } /** Return the atom with the given name. */ public Atom getAtom(String nm){ return getAtom(nm, 'A'); } /** Return the atom with the given name. */ private Atom getAtom(String nm, char code){ for(Atom a : atoms){ // atom has the appropriate name // and insertion code ' ' or 'A' if(a.getAtomLabel().equals(nm) && (a.getInsertionCode() == ' ' || a.getInsertionCode() == code)){ return a; } } return null; } /** Default to alternate location 'A'. */ public Atom findAtom(String name){ return findAtom(name, 'A'); } /** * Similar to getAtom(String name) but will search in * the previous residue if the name ends with '-' or * the next residue if the name ends with '+'. * * Maybe this should be rolled into one function but * prefer this way in case names genuinely end * with + or -. This method is only used by torsion * angle search functions. */ private Atom findAtom(String name, char code){ // atom is in previous or next residue // we need to go up to the chain and find the // relevant residue Residue r = this; if(name.endsWith("-") || name.endsWith("+")){ Chain chain = getParent(); int residueCount = chain.getResidueCount(); int residuePos = -1; for(int i = 0; i < residueCount; i++){ Residue res = chain.getResidue(i); if(res == this){ residuePos = i; break; } } if(residuePos != -1){ if(name.endsWith("-") && residuePos > 0){ r = chain.getResidue(residuePos - 1); }else if(name.endsWith("+") && residuePos < residueCount - 1){ r = chain.getResidue(residuePos + 1); }else{ r = null; } }else{ r = null; } // now we have found the residue, remove the // '-' or the '+' character so that we will // find it name = name.substring(0, name.length() - 1); } if(r == null) return null; return r.getAtom(name, code); } /** Is this residue a standard amino acid. */ public boolean isStandardAminoAcid(){ return Selection.aminoacidNames.contains(name.trim()); } /** Is this residue an ion. */ public boolean isIon(){ return Selection.ionNames.contains(name.trim()); } /** Is this a solvent residue. */ public boolean isSolvent(){ return Selection.solventNames.contains(name.trim()); } /** Is this a solvent residue. */ public boolean isNucleicAcid(){ return Selection.dnaNames.contains(name.trim()); } public String selectStatement(){ Chain chain = getParent(); String chainSelect = chain.selectStatement(); StringBuilder command = new StringBuilder(16); command.append("residue ").append(getNumber()); command.append(" and name '").append(getName()).append("'"); char insertionCode = getInsertionCode(); if(insertionCode != ' '){ command.append(" and insertion '").append(insertionCode).append("'"); } return command.append(" and ").append(chainSelect).toString(); } /** Apply a selection recursively. */ public int select(int state){ int selectCount = 0; for(Atom atom: atoms){ selectCount += atom.select(state); } return selectCount; } /** Print out a residue. */ @Override public String toString(){ Chain c = getParent(); return c.getName() + ":" + getNumber(); } public static final String ResidueColor = "color"; private static final String Torsions = "torsions"; private static final String TorsionRadius = "torsionRadius"; public static final String TorsionGreek = "torsionGreek"; public static final String TorsionFormat = "torsionFormat"; }