// $Id: Residue.java,v 1.8 2007/05/18 01:52:06 Sasha Buzko Exp $ // // Copyright (c) 2000-2002 San Diego Supercomputer Center (SDSC), // a facility operated jointly by the University of California, // San Diego (UCSD) and General Atomics, San Diego, California, USA. // // Users and possessors of this source code are hereby granted a // nonexclusive, royalty-free copyright and design patent license to // use this code in individual software. License is not granted for // commercial resale, in whole or in part, without prior written // permission from SDSC. This source is provided "AS IS" without express // or implied warranty of any kind. // // For further information, please see: http://mbt.sdsc.edu // // History: // $Log: Residue.java,v $ // Revision 1.8 2007/05/18 01:52:06 Sasha Buzko // *** empty log message *** // // Revision 1.7 2007/02/19 07:31:04 Sasha Buzko // *** empty log message *** // // Revision 1.6 2007/02/18 05:08:04 Sasha Buzko // *** empty log message *** // // Revision 1.5 2007/02/13 19:08:41 Sasha Buzko // *** empty log message *** // // Revision 1.4 2007/02/09 05:08:53 Sasha Buzko // *** empty log message *** // // Revision 1.3 2006/10/21 18:41:26 Sasha Buzko // *** empty log message *** // // Revision 1.2 2006/08/03 06:21:23 Sasha Buzko // *** empty log message *** // // Revision 1.1 2006/05/20 17:02:06 Sasha Buzko // Updated version // // Revision 1.2 2006/05/17 07:06:17 Sasha Buzko // *** empty log message *** // // Revision 1.1 2006/04/30 20:14:05 Sasha Buzko // New version of the app // // Revision 1.1 2006/04/15 19:42:27 Sasha Buzko // Initial commit // // Revision 1.2 2005/11/13 23:44:31 Administrator // *** empty log message *** // // Revision 1.1 2005/11/13 04:35:26 Administrator // *** empty log message *** // // Revision 1.9 2003/04/30 19:57:25 moreland // Corrected alpha atom index assignment bug. // // Revision 1.8 2003/04/30 17:50:34 moreland // Now correctly classifies nucleic acids. // Added binary search algorithm to find Atoms. // // Revision 1.7 2003/04/25 00:58:21 moreland // Removed COMPOUND_UNKNOWN classification since there are only 3 types "ever" (bourne). // // Revision 1.6 2003/04/24 21:04:31 moreland // Added getResidueId method. // // Revision 1.5 2003/04/24 17:13:33 moreland // Conformation type now defaults to the Conformation.TYPE_UNDEFINED type. // // Revision 1.4 2003/04/23 17:27:32 moreland // Removed StructureComponentID/scid and replaced it with a "structure" field // in the StructureComponent base class. // Changed "getType" method to "getStructureComponentType" to return dynamic // SC type (ie: class name). // Added residue classification (amino acid VS nucleic acid VS ligand) support. // Enabled compound code to be set when no Atoms exist (for pure sequence data). // Enabled adding/removing of Atom objects. // // Revision 1.3 2003/04/03 18:23:36 moreland // Residue is now a container of Atom objects (or empty for sequence data). // // Revision 1.2 2002/10/24 17:54:01 moreland // Provides implementation for the improved Structure API/implementation. // // Revision 1.1.1.1 2002/07/16 18:00:18 moreland // Imported sources // // Revision 1.0 2002/06/10 23:38:39 moreland // package edu.sdsc.mbt; import edu.sdsc.mbt.util.*; import edu.sdsc.mbt.viewables.StylesPreferences; import edu.sdsc.sirius.util.*; import java.util.*; /** * Implements a StructureComponent container for residue information. * This may be an amino acid residue, a nucleic acid residue, or a ligand. * This class generally contains a list of Atom records, though it is * perfectly fine to be empty when it is used only for sequence information. *

* See the "PROGRAMMING NOTE" section of the StructureComponent class. *

* @see edu.sdsc.mbt.StructureComponent * @see edu.sdsc.mbt.Structure * @see edu.sdsc.mbt.StructureComponentIterator * @see edu.sdsc.mbt.util.AminoAcidInfo *

* @author John L. Moreland */ public class Residue extends StructureComponent implements java.lang.Cloneable, java.io.Serializable { /** * Residue compound classification is an amino acid. */ public static final String COMPOUND_AMINO_ACID = "Amino Acid"; /** * Residue compound is a nucleic acid. */ public static final String COMPOUND_NUCLEIC_ACID = "Nucleic Acid"; /** * Residue compound classification is a ligand. */ public static final String COMPOUND_LIGAND = "Ligand"; /** * Residue compound classification as a deletion. */ public static final String COMPOUND_DELETION = "Deletion"; // List of residue compound classifications. public static final String COMPOUND_CLASSIFICATIONS[] = { COMPOUND_AMINO_ACID, COMPOUND_NUCLEIC_ACID, COMPOUND_LIGAND, COMPOUND_DELETION }; // The Atom index for the alpha (backbone) atom private int alphaAtomIndex = -1; private static final String aaAlphaAtomName = "CA"; private static final String naAlphaAtomName = "P"; // The Atom records (if any) for the residue. private Vector atoms = null; // The 3-letter residue compound code, or, "UNK" for UNKNOWN. // See the AminoAcids and NucleicAcids classes for details. private String compoundCode = "UNK"; // The compound classification for this residue. private String classification = COMPOUND_LIGAND; // The secondary structure conformation type assigned to this residue. private String conformationType = Conformation.TYPE_UNDEFINED; //position of the residue in the alignment private int position = 0; //position of the residue in the sequence private int number = 0; // The parent Fragment (if any) for the residue. private Fragment parentFragment = null; // The polymer "head" and "tail" atoms for this amino acid or nucleic acid // residue (or null for ligands) can be used to form polymer bonds // between adjacent residues. private Atom polymerHeadAtom = null; private Atom polymerTailAtom = null; // The well-known polymer "head" and "tail" atom names for // amino acid or nucleic acid residues. // This can be used to form polypeptide bonds between adjacent amino // acids, or nucleic acid bonds between adjacent nucleic acids. private static final String aaHeadAtomName = "N"; private static final String aaTailAtomName = "C"; private static final String naHeadAtomName = "P"; private static final String naTailAtomName = "O3'"; public Atom centerAtom;//for bump checking to quickly get the center of the Residue // // Constructors // /** * Constructor variant used when there will likely be no atom list * (eg: when only sequence data is loaded). */ public Residue( String compoundCode ) { this.compoundCode = compoundCode; } /** * Constructor variant used when there will likely be an atom list. */ public Residue( ) { } // // StructureComponent methods. // /** * Copy all of the field values from the parameter object into "this". */ public void copy( StructureComponent structureComponent ) { structure = structureComponent.structure; Residue residue = (Residue) structureComponent; compoundCode = residue.compoundCode; alphaAtomIndex = residue.alphaAtomIndex; } /** * Clone this object. */ public Object clone( ) throws CloneNotSupportedException { return super.clone( ); } private static String className = null; /** * This method returns the fully qualified name of this class. *

* This name is used by the StructureComponentRegistry class to enable * dynamic registration and discovery of new StructureComponent * sub-classes/types. The name is also used to create a unique integer * indentifier for each type in order to make run-time type comparisons * fast. */ public static String getClassName() { if ( className == null ) className = ((new Throwable()).getStackTrace())[0].getClassName(); return className; } /** * This method returns the fully qualified name of this class. */ public String getStructureComponentType( ) { return className; } // // Residue methods. // /** * Return the compound classification for this residue. * (eg: amino acid, nucleic acid, ligand, unknown). */ public String getClassification( ) { return classification; } /** * Set the 3-letter compound code for this residue. */ public void setCompoundCode( String compoundCode ) { this.compoundCode = compoundCode; if ( AminoAcidInfo.getNameFromCode( compoundCode ) != null ){ classification = COMPOUND_AMINO_ACID; } else if ( NucleicAcidInfo.getNameFromLetter( compoundCode ) != null ){ classification = COMPOUND_NUCLEIC_ACID; } else if ( DNAProperties.isNucleicAcid( compoundCode ) ){//just in case nucleic acids are denoted as three-letters classification = COMPOUND_NUCLEIC_ACID; } else if (DeletionInfo.getNameFromCode(compoundCode) != null){ classification = COMPOUND_DELETION; } else{ classification = COMPOUND_LIGAND; } } /** * Get the 3-letter compound code for this residue. */ public String getCompoundCode( ) { return compoundCode; } /** * Return the number of Atom records contained in this Residue. */ public int getAtomCount( ) { if ( atoms == null ) return 0; else return atoms.size(); } /** * Return the specified Atom record contained in this Residue. */ public Atom getAtom( int index ) { if ( atoms == null ) throw new IndexOutOfBoundsException( "residue has no atoms" ); return (Atom) atoms.elementAt( index ); } public int getAtomIndex(Atom atom){ if ( atoms == null ) throw new IndexOutOfBoundsException( "residue has no atoms" ); if (atom == null) throw new IndexOutOfBoundsException( "Null atom" ); return atoms.indexOf(atom); } /** * Return Vector of Atoms that are contained in this Residue. */ public Vector getAtoms(){ return atoms; } /** * Tests whether the Residue contains a particular Atom. */ public boolean containsAtom(Atom atom){ return atoms.contains(atom); } /** * Add an Atom record to this Residue. */ public void addAtom( Atom atom ) { if ( atom == null ) throw new IllegalArgumentException( "null atom" ); if ( atoms == null ) { atoms = new Vector( ); setCompoundCode( atom.compound ); } atoms.add( atom ); // Set the alphaAtomIndex, or the polymer head or tail atoms. if ( classification == COMPOUND_AMINO_ACID ) { if ( atom.name.equals( aaAlphaAtomName ) ) alphaAtomIndex = atoms.indexOf(atom); if ( atom.name.equals( aaHeadAtomName ) ) polymerHeadAtom = atom; if ( atom.name.equals( aaTailAtomName ) ) polymerTailAtom = atom; } else if ( classification == COMPOUND_NUCLEIC_ACID ) { if ( atom.name.equals( naAlphaAtomName ) ){ alphaAtomIndex = atoms.indexOf(atom); } if ( atom.name.equals( naHeadAtomName ) ) polymerHeadAtom = atom; if ( atom.name.equals( naTailAtomName ) ) polymerTailAtom = atom; } } /** * Remove all Atom records from this Residue. */ public void removeAllAtoms( ) { if ( atoms != null ) atoms.removeAllElements( ); atoms = null; setCompoundCode( "UNK" ); alphaAtomIndex = -1; polymerHeadAtom = null; polymerTailAtom = null; } public void removeAtom(Atom atom){ atoms.remove( atom ); // Just removed the alpha atom if ( this.getAtomIndex(atom) == alphaAtomIndex ) alphaAtomIndex = -1; // Adjust the alpha atom index if ( this.getAtomIndex(atom) < alphaAtomIndex ) alphaAtomIndex -= 1; if ( alphaAtomIndex < 0 ) alphaAtomIndex = -1; if ( atoms.size() <= 0 ) removeAllAtoms( ); if ( classification == COMPOUND_AMINO_ACID ) { if ( atom.name.equals( aaHeadAtomName ) ) polymerHeadAtom = null; else if ( atom.name.equals( aaTailAtomName ) ) polymerTailAtom = null; } else if ( classification == COMPOUND_NUCLEIC_ACID ) { if ( atom.name.equals( naHeadAtomName ) ) polymerHeadAtom = null; else if ( atom.name.equals( naTailAtomName ) ) polymerTailAtom = null; } } /** * Remove the specified Atom record from this Residue. */ public void removeAtom( int index ) { if ( atoms == null ) throw new IndexOutOfBoundsException( "residue has no atoms" ); Atom atom = getAtom( index ); atoms.remove( index ); // Just removed the alpha atom if ( index == alphaAtomIndex ) alphaAtomIndex = -1; // Adjust the alpha atom index if ( index < alphaAtomIndex ) alphaAtomIndex -= 1; if ( alphaAtomIndex < 0 ) alphaAtomIndex = -1; if ( atoms.size() <= 0 ) removeAllAtoms( ); if ( classification == COMPOUND_AMINO_ACID ) { if ( atom.name.equals( aaHeadAtomName ) ) polymerHeadAtom = null; else if ( atom.name.equals( aaTailAtomName ) ) polymerTailAtom = null; } else if ( classification == COMPOUND_NUCLEIC_ACID ) { if ( atom.name.equals( naHeadAtomName ) ) polymerHeadAtom = null; else if ( atom.name.equals( naTailAtomName ) ) polymerTailAtom = null; } } /** * Get the alpha (backbone) Atom (eg: "CA" or "P") index for this * amino acid or nucleic acid residue (or -1 for ligands). */ public int getAlphaAtomIndex( ) { return alphaAtomIndex; } /** * Get the alpha (backbone) Atom (eg: "CA" or "P") for this * amino acid or nucleic acid residue (or -1 for ligands). */ public Atom getAlphaAtom( ) { if ( atoms == null ) return null; if ( alphaAtomIndex < 0 ) return null; if ( alphaAtomIndex >= atoms.size() ) return null; return (Atom) atoms.elementAt( alphaAtomIndex ); } public void setAlphaAtom(Atom atom){ if (atoms.contains(atom)){ alphaAtomIndex = atoms.indexOf(atom); } } /** * Return the Hydrophobicity of the amino acid residue as a normalized * value from 0.0 to 1.0 inclusive. * See the AminoAcid class for a description of what method is used * to produce the hydrophobicity scale. */ public float getHydrophobicity( ) { // AminoAcid aminoAcid = AminoAcids.getByCode( compoundCode ); // return aminoAcid.getHydrophobicity( ); return AminoAcidInfo.getHydrophobicityFromCode( compoundCode ); } /** * Set the secondary structure conformation type that should be assigned * to this residue. */ public void setConformationType( String type ) { if ( type == null ) throw new IllegalArgumentException( "null type" ); // JLM DEBUG: We should throw an exception if the type is not one of // Conformation subclass type, or, Conformation.TYPE_UNDEFINED. conformationType = type; } /** * Get the secondary structure conformation type that is assigned * to this residue. */ public String getConformationType( ) { return conformationType; } /** * Get the chain id (as it is assigned in the first Atom record). * Return null if there are no atom records. */ public String getChainId( ) { if ( atoms == null ) return null; Atom atom = (Atom) atoms.elementAt( 0 ); if ( atom == null ) return null; return atom.chain_id; } public void setChainId(String id){ if ( atoms == null ) return; Atom atom = (Atom) atoms.elementAt( 0 ); if ( atom == null ) return; atom.chain_id = id; } /** * Get the residue id (as it is assigned in the first Atom record). * Return -1 if there are no atom records. */ public int getResidueId( ) { if ( atoms == null ) return -1; Atom atom = (Atom) atoms.elementAt( 0 ); if ( atom == null ) return -1; return atom.residue_id; } public void setResidueId(int id){ if (atoms != null){ for (int i = 0; i < atoms.size(); i++){ ((Atom)atoms.elementAt(i)).residue_id = id; } } } public void setNumber(int n){ number = n; } public int getNumber(){ return number; } public void setPosition(int i){ position = i; } public int getPosition(){ return position; } /** * Set the parent fragment (if any) for this residue. * Protected because only Chain should manage fragments. */ protected void setFragment( Fragment fragment ) { parentFragment = fragment; } /** * Get the parent fragment (if any) for this residue. */ public Fragment getFragment( ) { return parentFragment; } /** * Get the polymer "head" atom for this amino acid or nucleic acid residue * (or null for ligands). * This can be used to form polypeptide bonds between adjacent amino * acids, or nucleic acid bonds between adjacent nucleic acids. *

*/ public Atom getPolymerHeadAtom( ) { return polymerHeadAtom; } /** * Get the polymer "tail" atom for this amino acid or nucleic acid residue * (or null for ligands). * This can be used to form polypeptide bonds between adjacent amino * acids, or nucleic acid bonds between adjacent nucleic acids. *

*/ public Atom getPolymerTailAtom( ) { return polymerTailAtom; } /** * Set the alpha (backbone) Atom index for this * amino acid or nucleic acid residue. For for ligands this will be * set to -1 (ie: no valid alpha atom). For disordered residues * (that have no alpha atom) it may be set to an alternate index * so that applicatons may still draw backbone traces through the * residue. */ public void setAlphaAtomIndex( int index ) { alphaAtomIndex = index; } public void setClassification(String classification){ this.classification = classification; } public short render = (short)StylesPreferences.renderingMode; public short quality = (short)StylesPreferences.startupRenderingQuality; public boolean visible = true; public boolean isVisible(){ return visible; } public boolean ribbon = false; }