JAL-1807 Bob's JalviewJS prototype first commit
[jalviewjs.git] / src / jalview / analysis / CodingUtils.java
1 package jalview.analysis;
2
3 /**
4  * A utility class to provide encoding/decoding schemes for data.
5  * 
6  * @author gmcarstairs
7  *
8  */
9 public class CodingUtils
10 {
11
12   /*
13    * Number of bits used when encoding codon characters. 2 is enough for ACGT.
14    * To accommodate more (e.g. ambiguity codes), simply increase this number
15    * (and adjust unit tests to match).
16    */
17   private static final int CODON_ENCODING_BITSHIFT = 2;
18
19   /**
20    * Encode a codon from e.g. ['A', 'G', 'C'] to a number in the range 0 - 63.
21    * Converts lower to upper case, U to T, then assembles a binary value by
22    * encoding A/C/G/T as 00/01/10/11 respectively and shifting.
23    * 
24    * @param codon
25    * @return the encoded codon, or a negative number if unexpected characters
26    *         found
27    */
28   public static int encodeCodon(char[] codon)
29   {
30     if (codon == null)
31     {
32       return -1;
33     }
34     return encodeCodon(codon[2])
35             + (encodeCodon(codon[1]) << CODON_ENCODING_BITSHIFT)
36             + (encodeCodon(codon[0]) << (2 * CODON_ENCODING_BITSHIFT));
37   }
38
39   /**
40    * Encodes aA/cC/gG/tTuU as 0/1/2/3 respectively. Returns Integer.MIN_VALUE (a
41    * large negative value) for any other character.
42    * 
43    * @param c
44    * @return
45    */
46   public static int encodeCodon(char c)
47   {
48     int result = Integer.MIN_VALUE;
49     switch (c)
50     {
51     case 'A':
52     case 'a':
53       result = 0;
54       break;
55     case 'C':
56     case 'c':
57       result = 1;
58       break;
59     case 'G':
60     case 'g':
61       result = 2;
62       break;
63     case 'T':
64     case 't':
65     case 'U':
66     case 'u':
67       result = 3;
68       break;
69     }
70     return result;
71   }
72
73   /**
74    * Converts a binary encoded codon into an ['A', 'C', 'G'] (or 'T') triplet.
75    * 
76    * The two low-order bits encode for A/C/G/T as 0/1/2/3, etc.
77    * 
78    * @param encoded
79    * @return
80    */
81   public static char[] decodeCodon(int encoded)
82   {
83     char[] result = new char[3];
84     result[2] = decodeNucleotide(encoded & 3);
85     encoded = encoded >>> CODON_ENCODING_BITSHIFT;
86     result[1] = decodeNucleotide(encoded & 3);
87     encoded = encoded >>> CODON_ENCODING_BITSHIFT;
88     result[0] = decodeNucleotide(encoded & 3);
89     return result;
90   }
91
92   /**
93    * Convert value 0/1/2/3 to 'A'/'C'/'G'/'T'
94    * 
95    * @param i
96    * @return
97    */
98   public static char decodeNucleotide(int i)
99   {
100     char result = '0';
101     switch (i)
102     {
103     case 0:
104       result = 'A';
105       break;
106     case 1:
107       result = 'C';
108       break;
109     case 2:
110       result = 'G';
111       break;
112     case 3:
113       result = 'T';
114       break;
115     }
116     return result;
117   }
118
119 }