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 * Created on 01-21-2010 021 */ 022package org.biojava.nbio.core.sequence.transcription; 023 024import org.biojava.nbio.core.sequence.compound.AminoAcidCompound; 025import org.biojava.nbio.core.sequence.compound.NucleotideCompound; 026import org.biojava.nbio.core.sequence.io.IUPACParser.IUPACTable; 027import org.biojava.nbio.core.sequence.template.Compound; 028import org.biojava.nbio.core.sequence.template.CompoundSet; 029import org.biojava.nbio.core.util.Equals; 030import org.biojava.nbio.core.util.Hashcoder; 031 032import java.util.List; 033 034/** 035 * Provides a way of separating us from the specific {@link IUPACTable} even 036 * though this is the only implementing class for the interface. 037 * 038 * @author ayates 039 */ 040public interface Table { 041 042 List<Codon> getCodons(CompoundSet<NucleotideCompound> nucelotides, 043 CompoundSet<AminoAcidCompound> aminoAcids); 044 045 CompoundSet<Codon> getCodonCompoundSet( 046 final CompoundSet<NucleotideCompound> rnaCompounds, 047 final CompoundSet<AminoAcidCompound> aminoAcidCompounds); 048 049 /** 050 * Returns true if the given compound could have been a start amino acid; 051 * this does not assert if the codon that actually coded for the amino 052 * acid was a start codon. This is as accurate a call as we can make with an 053 * {@link AminoAcidCompound}. 054 */ 055 boolean isStart(AminoAcidCompound compound); 056 057 /** 058 * Instance of a Codon which is 3 {@link NucleotideCompound}s, its 059 * corresponding {@link AminoAcidCompound} and if it is a start or stop codon. 060 * The object implements hashCode & equals but according to the nucleotide 061 * compounds & not to the designation of it being a start, stop & amino 062 * acid compound 063 * 064 * @author ayates 065 * 066 */ 067 public static class Codon implements Compound { 068 069 private final CaseInsensitiveTriplet triplet; 070 private final boolean start; 071 private final boolean stop; 072 private final AminoAcidCompound aminoAcid; 073 private final String stringified; 074 075 public Codon(CaseInsensitiveTriplet triplet, AminoAcidCompound aminoAcid, boolean start, 076 boolean stop) { 077 this.triplet = triplet; 078 this.start = start; 079 this.stop = stop; 080 this.aminoAcid = aminoAcid; 081 this.stringified = triplet.toString(); 082 } 083 084 public Codon(CaseInsensitiveTriplet triplet) { 085 this(triplet, null, false, false); 086 } 087 088 public NucleotideCompound getOne() { 089 return triplet.getOne(); 090 } 091 092 public NucleotideCompound getTwo() { 093 return triplet.getTwo(); 094 } 095 096 public NucleotideCompound getThree() { 097 return triplet.getThree(); 098 } 099 100 public boolean isStart() { 101 return start; 102 } 103 104 public boolean isStop() { 105 return stop; 106 } 107 108 public AminoAcidCompound getAminoAcid() { 109 return aminoAcid; 110 } 111 112 public CaseInsensitiveTriplet getTriplet() { 113 return triplet; 114 } 115 116 @Override 117 public boolean equals(Object obj) { 118 boolean equals = false; 119 if(Equals.classEqual(this, obj)) { 120 Codon casted = (Codon) obj; 121 equals = Equals.equal(getTriplet(), casted.getTriplet()) && 122 Equals.equal(isStart(), casted.isStart()) && 123 Equals.equal(isStop(), casted.isStop()) && 124 Equals.equal(getAminoAcid(), casted.getAminoAcid()); 125 } 126 return equals; 127 } 128 129 @Override 130 public int hashCode() { 131 int result = Hashcoder.SEED; 132 result = Hashcoder.hash(result, getTriplet()); 133 result = Hashcoder.hash(result, isStop()); 134 result = Hashcoder.hash(result, isStart()); 135 result = Hashcoder.hash(result, getAminoAcid()); 136 return result; 137 } 138 139 @Override 140 public String toString() { 141 return stringified; 142 } 143 144 @Override 145 public boolean equalsIgnoreCase(Compound compound) { 146 return toString().equalsIgnoreCase(compound.toString()); 147 } 148 149 @Override 150 public String getDescription() { 151 throw new UnsupportedOperationException("Not supported"); 152 } 153 154 @Override 155 public String getLongName() { 156 throw new UnsupportedOperationException("Not supported"); 157 } 158 159 @Override 160 public Float getMolecularWeight() { 161 throw new UnsupportedOperationException("Not supported"); 162 } 163 164 @Override 165 public String getShortName() { 166 return stringified; 167 } 168 169 @Override 170 public void setDescription(String description) { 171 throw new UnsupportedOperationException("Not supported"); 172 } 173 174 @Override 175 public void setLongName(String longName) { 176 throw new UnsupportedOperationException("Not supported"); 177 } 178 179 @Override 180 public void setMolecularWeight(Float molecularWeight) { 181 throw new UnsupportedOperationException("Not supported"); 182 } 183 184 @Override 185 public void setShortName(String shortName) { 186 throw new UnsupportedOperationException("Not supported"); 187 } 188 } 189 190 /** 191 * Class used to hold three nucleotides together and allow for equality 192 * to be assessed in a case insensitive manner. 193 */ 194 public static class CaseInsensitiveTriplet { 195 196 private final NucleotideCompound one; 197 private final NucleotideCompound two; 198 private final NucleotideCompound three; 199 200 private transient boolean hashSet = false; 201 private transient int hash; 202 private transient boolean stringSet = false; 203 private transient String stringify; 204 205 public CaseInsensitiveTriplet(NucleotideCompound one, 206 NucleotideCompound two, NucleotideCompound three) { 207 this.one = one; 208 this.two = two; 209 this.three = three; 210 211 } 212 213 public NucleotideCompound getOne() { 214 return one; 215 } 216 217 public NucleotideCompound getTwo() { 218 return two; 219 } 220 221 public NucleotideCompound getThree() { 222 return three; 223 } 224 225 @Override 226 public boolean equals(Object obj) { 227 boolean equals = false; 228 if(Equals.classEqual(this, obj)) { 229 CaseInsensitiveTriplet casted = (CaseInsensitiveTriplet) obj; 230 return toString().equals(casted.toString()); 231 } 232 return equals; 233 } 234 235 @Override 236 public int hashCode() { 237 if(!hashSet) { 238 hash = toString().hashCode(); 239 hashSet = true; 240 } 241 return hash; 242 } 243 244 @Override 245 public String toString() { 246 if(!stringSet) { 247 stringify = getOne().getUpperedBase() + 248 getTwo().getUpperedBase() + 249 getThree().getUpperedBase(); 250 } 251 return stringify; 252 } 253 254 /** 255 * Attempts to provide an int version of this codon which multiplies 256 * each position by 257 */ 258 public int intValue() { 259 return (16 * compoundToInt(getOne())) + 260 (4 * compoundToInt(getTwo())) + 261 (compoundToInt(getThree())); 262 } 263 264 public int compoundToInt(NucleotideCompound c) { 265 char b = c.getUpperedBase().charAt(0); 266 return b; 267// int v = -1; 268// if('A' == b) { 269// v = 1; 270// } 271// else if('C' == b) { 272// v = 2; 273// } 274// else if('G' == b) { 275// v = 3; 276// } 277// else if('T' == b || 'U' == b) { 278// v = 4; 279// } 280// return v; 281 } 282 } 283}