001package com.hfg.bio.seq.translation;
002
003import com.hfg.util.BooleanUtil;
004import com.hfg.util.StringUtil;
005import com.hfg.xml.HfgXML;
006import com.hfg.xml.XMLName;
007import com.hfg.xml.XMLTag;
008
009//------------------------------------------------------------------------------
010/**
011 Codon container.
012 <div>
013  @author J. Alex Taylor, hairyfatguy.com
014 </div>
015 */
016//------------------------------------------------------------------------------
017// com.hfg Library
018//
019// This library is free software; you can redistribute it and/or
020// modify it under the terms of the GNU Lesser General Public
021// License as published by the Free Software Foundation; either
022// version 2.1 of the License, or (at your option) any later version.
023//
024// This library is distributed in the hope that it will be useful,
025// but WITHOUT ANY WARRANTY; without even the implied warranty of
026// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
027// Lesser General Public License for more details.
028//
029// You should have received a copy of the GNU Lesser General Public
030// License along with this library; if not, write to the Free Software
031// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
032//
033// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
034// jataylor@hairyfatguy.com
035//------------------------------------------------------------------------------
036
037public class Codon
038{
039   private String     mTriplet;
040   private Character  mAA;
041   private boolean    mContainsDegenerateBases;
042   private CodonUsage mCodonUsage;
043   private boolean    mIsInitiation;
044   private boolean    mIsAltInitiation;
045
046   // XML Tag names
047   public static final XMLName XML_CODON        = new XMLName("Codon", HfgXML.HFG_NAMESPACE);
048
049   // XML Attribute names
050   public static final XMLName XML_AA_ATT       = new XMLName("aa", HfgXML.HFG_NAMESPACE);
051   public static final XMLName XML_TRIPLET_ATT  = new XMLName("triplet", HfgXML.HFG_NAMESPACE);
052   public static final XMLName XML_INIT_ATT     = new XMLName("init", HfgXML.HFG_NAMESPACE);
053   public static final XMLName XML_ALT_INIT_ATT = new XMLName("altInit", HfgXML.HFG_NAMESPACE);
054
055   //###########################################################################
056   // CONSTRUCTORS
057   //###########################################################################
058
059   //---------------------------------------------------------------------------
060   public Codon(String inTriplet)
061   {
062      if (! StringUtil.isSet(inTriplet)
063          || 3 != inTriplet.length())
064      {
065         throw new RuntimeException("Codons must be three nucleotides long!");
066      }
067
068      setTriplet(inTriplet);
069   }
070
071   //---------------------------------------------------------------------------
072   public Codon(XMLTag inXMLTag)
073   {
074      inXMLTag.verifyTagName(XML_CODON);
075
076      setTriplet(inXMLTag.getAttributeValue(XML_TRIPLET_ATT));
077      setIsInitiation(BooleanUtil.valueOf(inXMLTag.getAttributeValue(XML_INIT_ATT)));
078      setIsAltInitiation(BooleanUtil.valueOf(inXMLTag.getAttributeValue(XML_ALT_INIT_ATT)));
079
080      String aa = inXMLTag.getAttributeValue(XML_AA_ATT);
081      {
082         if (StringUtil.isSet(aa))
083         {
084            if (aa.length() > 1)
085            {
086               throw new RuntimeException("The specified aa value " + StringUtil.singleQuote(aa) + " is longer than 1 character!");
087            }
088
089            mAA = aa.charAt(0);
090         }
091      }
092
093      XMLTag codonUsageTag = inXMLTag.getOptionalSubtagByName(CodonUsage.XML_CODON_USAGE);
094      if (codonUsageTag != null)
095      {
096         mCodonUsage = new CodonUsage(codonUsageTag);
097      }
098   }
099
100
101   //###########################################################################
102   // PUBLIC METHODS
103   //###########################################################################
104
105   //---------------------------------------------------------------------------
106   public Codon setAA(Character inValue)
107   {
108      mAA = inValue;
109      return this;
110   }
111
112   //---------------------------------------------------------------------------
113   public Character getAA()
114   {
115      return mAA;
116   }
117
118
119   //---------------------------------------------------------------------------
120   public Codon setIsInitiation(boolean inValue)
121   {
122      mIsInitiation = inValue;
123      return this;
124   }
125
126   //---------------------------------------------------------------------------
127   public boolean isInitiation()
128   {
129      return mIsInitiation;
130   }
131
132
133   //---------------------------------------------------------------------------
134   public Codon setIsAltInitiation(boolean inValue)
135   {
136      mIsAltInitiation = inValue;
137      return this;
138   }
139
140   //---------------------------------------------------------------------------
141   public boolean isAltInitiation()
142   {
143      return mIsAltInitiation;
144   }
145
146
147   //---------------------------------------------------------------------------
148   public Codon setCodonUsage(CodonUsage inValue)
149   {
150      mCodonUsage = inValue;
151      return this;
152   }
153
154   //---------------------------------------------------------------------------
155   public CodonUsage getCodonUsage()
156   {
157      return mCodonUsage;
158   }
159
160   //---------------------------------------------------------------------------
161   @Override
162   public String toString()
163   {
164      return mTriplet;
165   }
166
167   //---------------------------------------------------------------------------
168   public XMLTag toXMLTag()
169   {
170      XMLTag tag = new XMLTag(XML_CODON);
171
172      tag.setAttribute(XML_TRIPLET_ATT, mTriplet);
173      if (mAA != null)
174      {
175         tag.setAttribute(XML_AA_ATT, mAA);
176      }
177
178      if (mCodonUsage != null)
179      {
180         tag.addSubtag(mCodonUsage.toXMLTag());
181      }
182
183      if (isInitiation())
184      {
185         tag.setAttribute(XML_INIT_ATT, "true");
186      }
187      else if (isAltInitiation())
188      {
189         tag.setAttribute(XML_ALT_INIT_ATT, "true");
190      }
191
192      return tag;
193   }
194
195   //---------------------------------------------------------------------------
196   @Override
197   public boolean equals(Object inObj2)
198   {
199      boolean result = false;
200      if (inObj2 != null
201          && inObj2 instanceof Codon)
202      {
203         Codon codon2 = (Codon) inObj2;
204
205         result = toString().equals(codon2.toString());
206      }
207
208      return result;
209   }
210
211   //---------------------------------------------------------------------------
212   @Override
213   public int hashCode()
214   {
215      return toString().hashCode();
216   }
217
218   //---------------------------------------------------------------------------
219   public boolean containsDegenerateBases()
220   {
221      return mContainsDegenerateBases;
222   }
223
224   //###########################################################################
225   // PRIVATE METHODS
226   //###########################################################################
227
228   //---------------------------------------------------------------------------
229   private void setTriplet(String inValue)
230   {
231      mTriplet = inValue.toUpperCase().replaceAll("U", "T"); // Force everything into uppercase DNA
232
233      mContainsDegenerateBases = false;
234      for (Character nucleotide : mTriplet.toCharArray())
235      {
236         if (! "ATGC".contains(nucleotide + ""))
237         {
238            mContainsDegenerateBases = true;
239            break;
240         }
241      }
242   }
243
244}