JAL-1432 updated copyright notices
[jalview.git] / src / jalview / schemes / ResidueProperties.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.0b1)
3  * Copyright (C) 2014 The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
10  *  
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  * The Jalview Authors are detailed in the 'AUTHORS' file.
18  */
19 package jalview.schemes;
20
21 import java.util.*;
22 import java.util.List;
23
24 import java.awt.*;
25
26 public class ResidueProperties
27 {
28   public static Hashtable scoreMatrices = new Hashtable();
29
30   // Stores residue codes/names and colours and other things
31   public static final int[] aaIndex; // aaHash version 2.1.1 and below
32
33   public static final int[] nucleotideIndex;
34
35   public static final int[] purinepyrimidineIndex;
36
37   public static final Hashtable aa3Hash = new Hashtable();
38
39   public static final Hashtable aa2Triplet = new Hashtable();
40
41   public static final Hashtable nucleotideName = new Hashtable();
42
43   static
44   {
45     aaIndex = new int[255];
46     for (int i = 0; i < 255; i++)
47     {
48       aaIndex[i] = 23;
49     }
50
51     aaIndex['A'] = 0;
52     aaIndex['R'] = 1;
53     aaIndex['N'] = 2;
54     aaIndex['D'] = 3;
55     aaIndex['C'] = 4;
56     aaIndex['Q'] = 5;
57     aaIndex['E'] = 6;
58     aaIndex['G'] = 7;
59     aaIndex['H'] = 8;
60     aaIndex['I'] = 9;
61     aaIndex['L'] = 10;
62     aaIndex['K'] = 11;
63     aaIndex['M'] = 12;
64     aaIndex['F'] = 13;
65     aaIndex['P'] = 14;
66     aaIndex['S'] = 15;
67     aaIndex['T'] = 16;
68     aaIndex['W'] = 17;
69     aaIndex['Y'] = 18;
70     aaIndex['V'] = 19;
71     aaIndex['B'] = 20;
72     aaIndex['Z'] = 21;
73     aaIndex['X'] = 22;
74     aaIndex['U'] = 22;
75     aaIndex['a'] = 0;
76     aaIndex['r'] = 1;
77     aaIndex['n'] = 2;
78     aaIndex['d'] = 3;
79     aaIndex['c'] = 4;
80     aaIndex['q'] = 5;
81     aaIndex['e'] = 6;
82     aaIndex['g'] = 7;
83     aaIndex['h'] = 8;
84     aaIndex['i'] = 9;
85     aaIndex['l'] = 10;
86     aaIndex['k'] = 11;
87     aaIndex['m'] = 12;
88     aaIndex['f'] = 13;
89     aaIndex['p'] = 14;
90     aaIndex['s'] = 15;
91     aaIndex['t'] = 16;
92     aaIndex['w'] = 17;
93     aaIndex['y'] = 18;
94     aaIndex['v'] = 19;
95     aaIndex['b'] = 20;
96     aaIndex['z'] = 21;
97     aaIndex['x'] = 22;
98     aaIndex['u'] = 22; // TODO: selenocystine triplet and codons needed. also
99     // extend subt. matrices
100   }
101
102   /**
103    * maximum (gap) index for matrices involving protein alphabet
104    */
105   public final static int maxProteinIndex = 23;
106
107   /**
108    * maximum (gap) index for matrices involving nucleotide alphabet
109    */
110   public final static int maxNucleotideIndex = 10;
111
112   static
113   {
114     nucleotideIndex = new int[255];
115     for (int i = 0; i < 255; i++)
116     {
117       nucleotideIndex[i] = 10; // non-nucleotide symbols are all non-gap gaps.
118     }
119
120     nucleotideIndex['A'] = 0;
121     nucleotideIndex['a'] = 0;
122     nucleotideIndex['C'] = 1;
123     nucleotideIndex['c'] = 1;
124     nucleotideIndex['G'] = 2;
125     nucleotideIndex['g'] = 2;
126     nucleotideIndex['T'] = 3;
127     nucleotideIndex['t'] = 3;
128     nucleotideIndex['U'] = 4;
129     nucleotideIndex['u'] = 4;
130     nucleotideIndex['I'] = 5;
131     nucleotideIndex['i'] = 5;
132     nucleotideIndex['X'] = 6;
133     nucleotideIndex['x'] = 6;
134     nucleotideIndex['R'] = 7;
135     nucleotideIndex['r'] = 7;
136     nucleotideIndex['Y'] = 8;
137     nucleotideIndex['y'] = 8;
138     nucleotideIndex['N'] = 9;
139     nucleotideIndex['n'] = 9;
140
141     nucleotideName.put("A", "Adenine");
142     nucleotideName.put("a", "Adenine");
143     nucleotideName.put("G", "Guanine");
144     nucleotideName.put("g", "Guanine");
145     nucleotideName.put("C", "Cytosine");
146     nucleotideName.put("c", "Cytosine");
147     nucleotideName.put("T", "Thymine");
148     nucleotideName.put("t", "Thymine");
149     nucleotideName.put("U", "Uracil");
150     nucleotideName.put("u", "Uracil");
151     nucleotideName.put("I", "Inosine");
152     nucleotideName.put("i", "Inosine");
153     nucleotideName.put("X", "Xanthine");
154     nucleotideName.put("x", "Xanthine");
155     nucleotideName.put("R", "Unknown Purine");
156     nucleotideName.put("r", "Unknown Purine");
157     nucleotideName.put("Y", "Unknown Pyrimidine");
158     nucleotideName.put("y", "Unknown Pyrimidine");
159     nucleotideName.put("N", "Unknown");
160     nucleotideName.put("n", "Unknown");
161     nucleotideName.put("W", "Weak nucleotide (A or T)");
162     nucleotideName.put("w", "Weak nucleotide (A or T)");
163     nucleotideName.put("S", "Strong nucleotide (G or C)");
164     nucleotideName.put("s", "Strong nucleotide (G or C)");
165     nucleotideName.put("M", "Amino (A or C)");
166     nucleotideName.put("m", "Amino (A or C)");
167     nucleotideName.put("K", "Keto (G or T)");
168     nucleotideName.put("k", "Keto (G or T)");
169     nucleotideName.put("B", "Not A (G or C or T)");
170     nucleotideName.put("b", "Not A (G or C or T)");
171     nucleotideName.put("H", "Not G (A or C or T)");
172     nucleotideName.put("h", "Not G (A or C or T)");
173     nucleotideName.put("D", "Not C (A or G or T)");
174     nucleotideName.put("d", "Not C (A or G or T)");
175     nucleotideName.put("V", "Not T (A or G or C");
176     nucleotideName.put("v", "Not T (A or G or C");
177
178   }
179
180   static
181   {
182     purinepyrimidineIndex = new int[255];
183     for (int i = 0; i < 255; i++)
184     {
185       purinepyrimidineIndex[i] = 3; // non-nucleotide symbols are all non-gap
186       // gaps.
187     }
188
189     purinepyrimidineIndex['A'] = 0;
190     purinepyrimidineIndex['a'] = 0;
191     purinepyrimidineIndex['C'] = 1;
192     purinepyrimidineIndex['c'] = 1;
193     purinepyrimidineIndex['G'] = 0;
194     purinepyrimidineIndex['g'] = 0;
195     purinepyrimidineIndex['T'] = 1;
196     purinepyrimidineIndex['t'] = 1;
197     purinepyrimidineIndex['U'] = 1;
198     purinepyrimidineIndex['u'] = 1;
199     purinepyrimidineIndex['I'] = 2;
200     purinepyrimidineIndex['i'] = 2;
201     purinepyrimidineIndex['X'] = 2;
202     purinepyrimidineIndex['x'] = 2;
203     purinepyrimidineIndex['R'] = 0;
204     purinepyrimidineIndex['r'] = 0;
205     purinepyrimidineIndex['Y'] = 1;
206     purinepyrimidineIndex['y'] = 1;
207     purinepyrimidineIndex['N'] = 2;
208     purinepyrimidineIndex['n'] = 2;
209   }
210
211   static
212   {
213     aa3Hash.put("ALA", new Integer(0));
214     aa3Hash.put("ARG", new Integer(1));
215     aa3Hash.put("ASN", new Integer(2));
216     aa3Hash.put("ASP", new Integer(3)); // D
217     aa3Hash.put("CYS", new Integer(4));
218     aa3Hash.put("GLN", new Integer(5)); // Q
219     aa3Hash.put("GLU", new Integer(6)); // E
220     aa3Hash.put("GLY", new Integer(7));
221     aa3Hash.put("HIS", new Integer(8));
222     aa3Hash.put("ILE", new Integer(9));
223     aa3Hash.put("LEU", new Integer(10));
224     aa3Hash.put("LYS", new Integer(11));
225     aa3Hash.put("MET", new Integer(12));
226     aa3Hash.put("PHE", new Integer(13));
227     aa3Hash.put("PRO", new Integer(14));
228     aa3Hash.put("SER", new Integer(15));
229     aa3Hash.put("THR", new Integer(16));
230     aa3Hash.put("TRP", new Integer(17));
231     aa3Hash.put("TYR", new Integer(18));
232     aa3Hash.put("VAL", new Integer(19));
233     // IUB Nomenclature for ambiguous peptides
234     aa3Hash.put("ASX", new Integer(20)); // "B";
235     aa3Hash.put("GLX", new Integer(21)); // X
236     aa3Hash.put("XAA", new Integer(22)); // X unknown
237     aa3Hash.put("-", new Integer(23));
238     aa3Hash.put("*", new Integer(23));
239     aa3Hash.put(".", new Integer(23));
240     aa3Hash.put(" ", new Integer(23));
241     aa3Hash.put("Gap", new Integer(23));
242   }
243
244   static
245   {
246     aa2Triplet.put("A", "ALA");
247     aa2Triplet.put("a", "ALA");
248     aa2Triplet.put("R", "ARG");
249     aa2Triplet.put("r", "ARG");
250     aa2Triplet.put("N", "ASN");
251     aa2Triplet.put("n", "ASN");
252     aa2Triplet.put("D", "ASP");
253     aa2Triplet.put("d", "ASP");
254     aa2Triplet.put("C", "CYS");
255     aa2Triplet.put("c", "CYS");
256     aa2Triplet.put("Q", "GLN");
257     aa2Triplet.put("q", "GLN");
258     aa2Triplet.put("E", "GLU");
259     aa2Triplet.put("e", "GLU");
260     aa2Triplet.put("G", "GLY");
261     aa2Triplet.put("g", "GLY");
262     aa2Triplet.put("H", "HIS");
263     aa2Triplet.put("h", "HIS");
264     aa2Triplet.put("I", "ILE");
265     aa2Triplet.put("i", "ILE");
266     aa2Triplet.put("L", "LEU");
267     aa2Triplet.put("l", "LEU");
268     aa2Triplet.put("K", "LYS");
269     aa2Triplet.put("k", "LYS");
270     aa2Triplet.put("M", "MET");
271     aa2Triplet.put("m", "MET");
272     aa2Triplet.put("F", "PHE");
273     aa2Triplet.put("f", "PHE");
274     aa2Triplet.put("P", "PRO");
275     aa2Triplet.put("p", "PRO");
276     aa2Triplet.put("S", "SER");
277     aa2Triplet.put("s", "SER");
278     aa2Triplet.put("T", "THR");
279     aa2Triplet.put("t", "THR");
280     aa2Triplet.put("W", "TRP");
281     aa2Triplet.put("w", "TRP");
282     aa2Triplet.put("Y", "TYR");
283     aa2Triplet.put("y", "TYR");
284     aa2Triplet.put("V", "VAL");
285     aa2Triplet.put("v", "VAL");
286   }
287
288   public static final String[] aa =
289   { "A", "R", "N", "D", "C", "Q", "E", "G", "H", "I", "L", "K", "M", "F",
290       "P", "S", "T", "W", "Y", "V", "B", "Z", "X", "_", "*", ".", " " };
291
292   public static final Color midBlue = new Color(100, 100, 255);
293
294   public static final Vector scaleColours = new Vector();
295
296   static
297   {
298     scaleColours.addElement(new Color(114, 0, 147));
299     scaleColours.addElement(new Color(156, 0, 98));
300     scaleColours.addElement(new Color(190, 0, 0));
301     scaleColours.addElement(Color.red);
302     scaleColours.addElement(new Color(255, 125, 0));
303     scaleColours.addElement(Color.orange);
304     scaleColours.addElement(new Color(255, 194, 85));
305     scaleColours.addElement(Color.yellow);
306     scaleColours.addElement(new Color(255, 255, 181));
307     scaleColours.addElement(Color.white);
308   }
309
310   public static final Color[] taylor =
311   { new Color(204, 255, 0), // A Greenish-yellowy-yellow
312       new Color(0, 0, 255), // R Blueish-bluey-blue
313       new Color(204, 0, 255), // N Blueish-reddy-blue
314       new Color(255, 0, 0), // D Reddish-reddy-red
315       new Color(255, 255, 0), // C Yellowish-yellowy-yellow
316       new Color(255, 0, 204), // Q Reddish-bluey-red
317       new Color(255, 0, 102), // E Blueish-reddy-red
318       new Color(255, 153, 0), // G Yellowy-reddy-yellow
319       new Color(0, 102, 255), // H Greenish-bluey-blue
320       new Color(102, 255, 0), // I Greenish-yellowy-green
321       new Color(51, 255, 0), // L Yellowish-greeny-green
322       new Color(102, 0, 255), // K Reddish-bluey-blue
323       new Color(0, 255, 0), // M Greenish-greeny-green
324       new Color(0, 255, 102), // F Blueish-greeny-green
325       new Color(255, 204, 0), // P Reddish-yellowy-yellow
326       new Color(255, 51, 0), // S Yellowish-reddy-red
327       new Color(255, 102, 0), // T Reddish-yellowy-red
328       new Color(0, 204, 255), // W Blueish-greeny-green
329       new Color(0, 255, 204), // Y Greenish-bluey-green
330       new Color(153, 255, 0), // V Yellowish-greeny-yellow
331       Color.white, // B
332       Color.white, // Z
333       Color.white, // X
334       Color.white, // -
335       Color.white, // *
336       Color.white // .
337   };
338
339   public static final Color[] nucleotide =
340   { new Color(100, 247, 63), // A
341       new Color(255, 179, 64), // C
342       new Color(235, 65, 60), // G
343       new Color(60, 136, 238), // T
344       new Color(60, 136, 238), // U
345       Color.white, // I (inosine)
346       Color.white, // X (xanthine)
347       Color.white, // R
348       Color.white, // Y
349       Color.white, // N
350       Color.white, // Gap
351   };
352
353   // Added for PurinePyrimidineColourScheme
354   public static final Color[] purinepyrimidine =
355   { new Color(255, 131, 250), // A, G, R purines purplish/orchid
356       new Color(64, 224, 208), // C,U, T, Y pyrimidines turquoise
357       Color.white, // all other nucleotides
358       Color.white // Gap
359   };
360
361   // Zappo
362   public static final Color[] zappo =
363   { Color.pink, // A
364       midBlue, // R
365       Color.green, // N
366       Color.red, // D
367       Color.yellow, // C
368       Color.green, // Q
369       Color.red, // E
370       Color.magenta, // G
371       midBlue,// Color.red, // H
372       Color.pink, // I
373       Color.pink, // L
374       midBlue, // K
375       Color.pink, // M
376       Color.orange, // F
377       Color.magenta, // P
378       Color.green, // S
379       Color.green, // T
380       Color.orange, // W
381       Color.orange, // Y
382       Color.pink, // V
383       Color.white, // B
384       Color.white, // Z
385       Color.white, // X
386       Color.white, // -
387       Color.white, // *
388       Color.white, // .
389       Color.white // ' '
390   };
391
392   // Dunno where I got these numbers from
393   public static final double[] hyd2 =
394   { 0.62, // A
395       0.29, // R
396       -0.90, // N
397       -0.74, // D
398       1.19, // C
399       0.48, // Q
400       -0.40, // E
401       1.38, // G
402       -1.50, // H
403       1.06, // I
404       0.64, // L
405       -0.78, // K
406       0.12, // M
407       -0.85, // F
408       -2.53, // P
409       -0.18, // S
410       -0.05, // T
411       1.08, // W
412       0.81, // Y
413       0.0, // V
414       0.26, // B
415       0.0, // Z
416       0.0 // X
417   };
418
419   public static final double[] helix =
420   { 1.42, 0.98, 0.67, 1.01, 0.70, 1.11, 1.51, 0.57, 1.00, 1.08, 1.21, 1.16,
421       1.45, 1.13, 0.57, 0.77, 0.83, 1.08, 0.69, 1.06, 0.84, 1.31, 1.00, 0.0 };
422
423   public static final double helixmin = 0.57;
424
425   public static final double helixmax = 1.51;
426
427   public static final double[] strand =
428   { 0.83, 0.93, 0.89, 0.54, 1.19, 1.10, 0.37, 0.75, 0.87, 1.60, 1.30, 0.74,
429       1.05, 1.38, 0.55, 0.75, 1.19, 1.37, 1.47, 1.70, 0.72, 0.74, 1.0, 0.0 };
430
431   public static final double strandmin = 0.37;
432
433   public static final double strandmax = 1.7;
434
435   public static final double[] turn =
436   { 0.66, 0.95, 1.56, 1.46, 1.19, 0.98, 0.74, 1.56, 0.95, 0.47, 0.59, 1.01,
437       0.60, 0.60, 1.52, 1.43, 0.96, 0.96, 1.14, 0.50, 1.51, 0.86, 1.00, 0,
438       0 };
439
440   public static final double turnmin = 0.47;
441
442   public static final double turnmax = 1.56;
443
444   public static final double[] buried =
445   { 1.7, 0.1, 0.4, 0.4, 4.6, 0.3, 0.3, 1.8, 0.8, 3.1, 2.4, 0.05, 1.9, 2.2,
446       0.6, 0.8, 0.7, 1.6, 0.5, 2.9, 0.4, 0.3, 1.358, 0.00 };
447
448   public static final double buriedmin = 0.05;
449
450   public static final double buriedmax = 4.6;
451
452   // This is hydropathy index
453   // Kyte, J., and Doolittle, R.F., J. Mol. Biol.
454   // 1157, 105-132, 1982
455   public static final double[] hyd =
456   { 1.8, -4.5, -3.5, -3.5, 2.5, -3.5, -3.5, -0.4, -3.2, 4.5, 3.8, -3.9,
457       1.9, 2.8, -1.6, -0.8, -0.7, -0.9, -1.3, 4.2, -3.5, -3.5, -0.49, 0.0 };
458
459   public static final double hydmax = 4.5;
460
461   public static final double hydmin = -3.9;
462
463   // public static final double hydmax = 1.38;
464   // public static final double hydmin = -2.53;
465   private static final int[][] BLOSUM62 =
466   {
467       { 4, -1, -2, -2, 0, -1, -1, 0, -2, -1, -1, -1, -1, -2, -1, 1, 0, -3,
468           -2, 0, -2, -1, 0, -4 },
469       { -1, 5, 0, -2, -3, 1, 0, -2, 0, -3, -2, 2, -1, -3, -2, -1, -1, -3,
470           -2, -3, -1, 0, -1, -4 },
471       { -2, 0, 6, 1, -3, 0, 0, 0, 1, -3, -3, 0, -2, -3, -2, 1, 0, -4, -2,
472           -3, 3, 0, -1, -4 },
473       { -2, -2, 1, 6, -3, 0, 2, -1, -1, -3, -4, -1, -3, -3, -1, 0, -1, -4,
474           -3, -3, 4, 1, -1, -4 },
475       { 0, 3, -3, -3, 9, -3, -4, -3, -3, -1, -1, -3, -1, -2, -3, -1, -1,
476           -2, -2, -1, -3, -3, -2, -4 },
477       { -1, 1, 0, 0, -3, 5, 2, -2, 0, -3, -2, 1, 0, -3, -1, 0, -1, -2, -1,
478           -2, 0, 3, -1, -4 },
479       { -1, 0, 0, 2, -4, 2, 5, -2, 0, -3, -3, 1, -2, -3, -1, 0, -1, -3, -2,
480           -2, 1, 4, -1, -4 },
481       { 0, -2, 0, -1, -3, -2, -2, 6, -2, -4, -4, -2, -3, -3, -2, 0, -2, -2,
482           -3, -3, -1, -2, -1, -4 },
483       { -2, 0, 1, -1, -3, 0, 0, -2, 8, -3, -3, -1, -2, -1, -2, -1, -2, -2,
484           2, -3, 0, 0, -1, -4 },
485       { -1, -3, -3, -3, -1, -3, -3, -4, -3, 4, 2, -3, 1, 0, -3, -2, -1, -3,
486           -1, 3, -3, -3, -1, -4 },
487       { -1, -2, -3, -4, -1, -2, -3, -4, -3, 2, 4, -2, 2, 0, -3, -2, -1, -2,
488           -1, 1, -4, -3, -1, -4 },
489       { -1, 2, 0, -1, -3, 1, 1, -2, -1, -3, -2, 5, -1, -3, -1, 0, -1, -3,
490           -2, -2, 0, 1, -1, -4 },
491       { -1, -1, -2, -3, -1, 0, -2, -3, -2, 1, 2, -1, 5, 0, -2, -1, -1, -1,
492           -1, 1, -3, -1, -1, -4 },
493       { -2, -3, -3, -3, -2, -3, -3, -3, -1, 0, 0, -3, 0, 6, -4, -2, -2, 1,
494           3, -1, -3, -3, -1, -4 },
495       { -1, -2, -2, -1, -3, -1, -1, -2, -2, -3, -3, -1, -2, -4, 7, -1, -1,
496           -4, -3, -2, -2, -1, -2, -4 },
497       { 1, -1, 1, 0, -1, 0, 0, 0, -1, -2, -2, 0, -1, -2, -1, 4, 1, -3, -2,
498           -2, 0, 0, 0, -4 },
499       { 0, -1, 0, -1, -1, -1, -1, -2, -2, -1, -1, -1, -1, -2, -1, 1, 5, -2,
500           -2, 0, -1, -1, 0, -4 },
501       { -3, -3, -4, -4, -2, -2, -3, -2, -2, -3, -2, -3, -1, 1, -4, -3, -2,
502           11, 2, -3, -4, -3, -2, -4 },
503       { -2, -2, -2, -3, -2, -1, -2, -3, 2, -1, -1, -2, -1, 3, -3, -2, -2,
504           2, 7, -1, -3, -2, -1, -4 },
505       { 0, -3, -3, -3, -1, -2, -2, -3, -3, 3, 1, -2, 1, -1, -2, -2, 0, -3,
506           -1, 4, -3, -2, -1, -4 },
507       { -2, -1, 3, 4, -3, 0, 1, -1, 0, -3, -4, 0, -3, -3, -2, 0, -1, -4,
508           -3, -3, 4, 1, -1, -4 },
509       { -1, 0, 0, 1, -3, 3, 4, -2, 0, -3, -3, 1, -1, -3, -1, 0, -1, -3, -2,
510           -2, 1, 4, -1, -4 },
511       { 0, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, 0, 0,
512           -2, -1, -1, -1, -1, -1, -4 },
513       { -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4,
514           -4, -4, -4, -4, -4, -4, 1 }, };
515
516   static final int[][] PAM250 =
517   {
518       { 2, -2, 0, 0, -2, 0, 0, 1, -1, -1, -2, -1, -1, -3, 1, 1, 1, -6, -3,
519           0, 0, 0, 0, -8 },
520       { -2, 6, 0, -1, -4, 1, -1, -3, 2, -2, -3, 3, 0, -4, 0, 0, -1, 2, -4,
521           -2, -1, 0, -1, -8 },
522       { 0, 0, 2, 2, -4, 1, 1, 0, 2, -2, -3, 1, -2, -3, 0, 1, 0, -4, -2, -2,
523           2, 1, 0, -8 },
524       { 0, -1, 2, 4, -5, 2, 3, 1, 1, -2, -4, 0, -3, -6, -1, 0, 0, -7, -4,
525           -2, 3, 3, -1, -8 },
526       { -2, -4, -4, -5, 12, -5, -5, -3, -3, -2, -6, -5, -5, -4, -3, 0, -2,
527           -8, 0, -2, -4, -5, -3, -8 },
528       { 0, 1, 1, 2, -5, 4, 2, -1, 3, -2, -2, 1, -1, -5, 0, -1, -1, -5, -4,
529           -2, 1, 3, -1, -8 },
530       { 0, -1, 1, 3, -5, 2, 4, 0, 1, -2, -3, 0, -2, -5, -1, 0, 0, -7, -4,
531           -2, 3, 3, -1, -8 },
532       { 1, -3, 0, 1, -3, -1, 0, 5, -2, -3, -4, -2, -3, -5, 0, 1, 0, -7, -5,
533           -1, 0, 0, -1, -8 },
534       { -1, 2, 2, 1, -3, 3, 1, -2, 6, -2, -2, 0, -2, -2, 0, -1, -1, -3, 0,
535           -2, 1, 2, -1, -8 },
536       { -1, -2, -2, -2, -2, -2, -2, -3, -2, 5, 2, -2, 2, 1, -2, -1, 0, -5,
537           -1, 4, -2, -2, -1, -8 },
538       { -2, -3, -3, -4, -6, -2, -3, -4, -2, 2, 6, -3, 4, 2, -3, -3, -2, -2,
539           -1, 2, -3, -3, -1, -8 },
540       { -1, 3, 1, 0, -5, 1, 0, -2, 0, -2, -3, 5, 0, -5, -1, 0, 0, -3, -4,
541           -2, 1, 0, -1, -8 },
542       { -1, 0, -2, -3, -5, -1, -2, -3, -2, 2, 4, 0, 6, 0, -2, -2, -1, -4,
543           -2, 2, -2, -2, -1, -8 },
544       { -3, -4, -3, -6, -4, -5, -5, -5, -2, 1, 2, -5, 0, 9, -5, -3, -3, 0,
545           7, -1, -4, -5, -2, -8 },
546       { 1, 0, 0, -1, -3, 0, -1, 0, 0, -2, -3, -1, -2, -5, 6, 1, 0, -6, -5,
547           -1, -1, 0, -1, -8 },
548       { 1, 0, 1, 0, 0, -1, 0, 1, -1, -1, -3, 0, -2, -3, 1, 2, 1, -2, -3,
549           -1, 0, 0, 0, -8 },
550       { 1, -1, 0, 0, -2, -1, 0, 0, -1, 0, -2, 0, -1, -3, 0, 1, 3, -5, -3,
551           0, 0, -1, 0, -8 },
552       { -6, 2, -4, -7, -8, -5, -7, -7, -3, -5, -2, -3, -4, 0, -6, -2, -5,
553           17, 0, -6, -5, -6, -4, -8 },
554       { -3, -4, -2, -4, 0, -4, -4, -5, 0, -1, -1, -4, -2, 7, -5, -3, -3, 0,
555           10, -2, -3, -4, -2, -8 },
556       { 0, -2, -2, -2, -2, -2, -2, -1, -2, 4, 2, -2, 2, -1, -1, -1, 0, -6,
557           -2, 4, -2, -2, -1, -8 },
558       { 0, -1, 2, 3, -4, 1, 3, 0, 1, -2, -3, 1, -2, -4, -1, 0, 0, -5, -3,
559           -2, 3, 2, -1, -8 },
560       { 0, 0, 1, 3, -5, 3, 3, 0, 2, -2, -3, 0, -2, -5, 0, 0, -1, -6, -4,
561           -2, 2, 3, -1, -8 },
562       { 0, -1, 0, -1, -3, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, 0, 0, -4,
563           -2, -1, -1, -1, -1, -8 },
564       { -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
565           -8, -8, -8, -8, -8, -8, 1 }, };
566
567   public static final Hashtable ssHash = new Hashtable(); // stores the number
568   // value of the aa
569
570   static
571   {
572     ssHash.put("H", Color.magenta);
573     ssHash.put("E", Color.yellow);
574     ssHash.put("-", Color.white);
575     ssHash.put(".", Color.white);
576     ssHash.put("S", Color.cyan);
577     ssHash.put("T", Color.blue);
578     ssHash.put("G", Color.pink);
579     ssHash.put("I", Color.pink);
580     ssHash.put("B", Color.yellow);
581   }
582
583   /*
584    * new Color(60, 136, 238), // U Color.white, // I Color.white, // X
585    * Color.white, // R Color.white, // Y Color.white, // N Color.white, // Gap
586    */
587
588   // JBPNote: patch matrix for T/U equivalence when working with DNA or RNA.
589   // Will equate sequences if working with mixed nucleotide sets.
590   // treats T and U identically. R and Y weak equivalence with AG and CTU.
591   // N matches any other base weakly
592   //
593   static final int[][] DNA =
594   {
595   { 10, -8, -8, -8, -8, 1, 1, 1, -8, 1, 1 }, // A
596       { -8, 10, -8, -8, -8, 1, 1, -8, 1, 1, 1 }, // C
597       { -8, -8, 10, -8, -8, 1, 1, 1, -8, 1, 1 }, // G
598       { -8, -8, -8, 10, 10, 1, 1, -8, 1, 1, 1 }, // T
599       { -8, -8, -8, 10, 10, 1, 1, -8, 1, 1, 1 }, // U
600       { 1, 1, 1, 1, 1, 10, 0, 0, 0, 1, 1 }, // I
601       { 1, 1, 1, 1, 1, 0, 10, 0, 0, 1, 1 }, // X
602       { 1, -8, 1, -8, -8, 0, 0, 10, -8, 1, 1 }, // R
603       { -8, 1, -8, 1, 1, 0, 0, -8, 10, 1, 1 }, // Y
604       { 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 1 }, // N
605       { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // -
606   };
607   /**
608    * register matrices in list
609    */
610   static
611   {
612     scoreMatrices.put("BLOSUM62", new ScoreMatrix("BLOSUM62", BLOSUM62, 0));
613     scoreMatrices.put("PAM250", new ScoreMatrix("PAM250", PAM250, 0));
614     scoreMatrices.put("DNA", new ScoreMatrix("DNA", DNA, 1));
615
616   }
617
618   public static final Color[] pidColours =
619   { midBlue, new Color(153, 153, 255),
620       // Color.lightGray,
621       new Color(204, 204, 255), };
622
623   public static final float[] pidThresholds =
624   { 80, 60, 40, };
625
626   public static Hashtable codonHash = new Hashtable();
627
628   public static Vector Lys = new Vector();
629
630   public static Vector Asn = new Vector();
631
632   public static Vector Gln = new Vector();
633
634   public static Vector His = new Vector();
635
636   public static Vector Glu = new Vector();
637
638   public static Vector Asp = new Vector();
639
640   public static Vector Tyr = new Vector();
641
642   public static Vector Thr = new Vector();
643
644   public static Vector Pro = new Vector();
645
646   public static Vector Ala = new Vector();
647
648   public static Vector Ser = new Vector();
649
650   public static Vector Arg = new Vector();
651
652   public static Vector Gly = new Vector();
653
654   public static Vector Trp = new Vector();
655
656   public static Vector Cys = new Vector();
657
658   public static Vector Ile = new Vector();
659
660   public static Vector Met = new Vector();
661
662   public static Vector Leu = new Vector();
663
664   public static Vector Val = new Vector();
665
666   public static Vector Phe = new Vector();
667
668   public static Vector STOP = new Vector();
669
670   static
671   {
672     codonHash.put("K", Lys);
673     codonHash.put("N", Asn);
674     codonHash.put("Q", Gln);
675     codonHash.put("H", His);
676     codonHash.put("E", Glu);
677     codonHash.put("D", Asp);
678     codonHash.put("Y", Tyr);
679     codonHash.put("T", Thr);
680     codonHash.put("P", Pro);
681     codonHash.put("A", Ala);
682     codonHash.put("S", Ser);
683     codonHash.put("R", Arg);
684     codonHash.put("G", Gly);
685     codonHash.put("W", Trp);
686     codonHash.put("C", Cys);
687     codonHash.put("I", Ile);
688     codonHash.put("M", Met);
689     codonHash.put("L", Leu);
690     codonHash.put("V", Val);
691     codonHash.put("F", Phe);
692     codonHash.put("STOP", STOP);
693   }
694
695   /**
696    * Nucleotide Ambiguity Codes 
697    */
698   public static final Hashtable<String,String[]> ambiguityCodes=new Hashtable<String,String[]>();
699   /**
700    * Codon triplets with additional symbols for unambiguous codons that include ambiguity codes
701    */
702   public static final Hashtable<String,String> codonHash2 = new Hashtable<String,String>();
703   
704   /**
705    * all ambiguity codes for a given base
706    */
707   public final static Hashtable<String,List<String>> _ambiguityCodes = new Hashtable<String,List<String>>();
708
709
710   static
711   {
712     /**
713      * 3.2. Purine (adenine or guanine): R
714      * 
715      * R is the symbol previously recommended [1].
716      */
717     ambiguityCodes.put("R", new String[]
718     { "A", "G" });
719
720     /**
721      * 3.3. Pyrimidine (thymine or cytosine): Y
722      * 
723      * Y is the symbol previously recommended [1].
724      */
725     ambiguityCodes.put("Y", new String[]
726     { "T", "C" });
727     /**
728      * 3.4. Adenine or thymine: W
729      * 
730      * Although several diverse symbols have been used for this pair, (and for
731      * the reciprocal pair G+C), only two symbols have a rational basis, L and
732      * W: L derives from DNA density (light; G+C - heavy - would thus be H); W
733      * derives from the strength of the hydrogen bonding interaction between the
734      * base pairs (weak for A+T: G +C - strong - would thus be S). However, the
735      * system recommended for the three-base series (not-A = B, etc., see below,
736      * section 3.8) rules out H as this would be not-G. W is thus recommended.
737      */
738     ambiguityCodes.put("W", new String[]
739     { "A", "T" });
740     /**
741      * 3.5. Guanine or cytosine: S
742      * 
743      * The choice of this symbol is discussed above in section 3.4.
744      */
745     ambiguityCodes.put("S", new String[]
746     { "G", "C" });
747     /**
748      * 3.6. Adenine or cytosine: M
749      * 
750      * There are few common features between A and C. The presence of an NH2
751      * group in similar positions on both bases (Fig. 1) makes possible a
752      * logically derived symbol. A and N being ruled out, M (from aMino) is
753      * recommended.
754      * 
755      * 
756      * Fig. 1. Origin of the symbols M and K The four bases are drawn so as to
757      * show the relationship between adenine and cytosine on the one hand, which
758      * both have aMino groups at the ring position most distant from the point
759      * of attachment to the sugar, and between guanine and thymine on the other,
760      * which both have Keto groups at the corresponding position. The ring atoms
761      * are numbered as recommended [24-26], although for the present purpose
762      * this has the disadvantage of giving discordant numbers to the
763      * corresponding positions.
764      */
765     ambiguityCodes.put("M", new String[]
766     { "A", "C" });
767     /**
768      * 3.7. Guanine or thymine: K By analogy with A and C (section 3.6), both G
769      * and T have Keto groups in similar positions (Fig. 1).
770      */
771     ambiguityCodes.put("K", new String[]
772     { "G", "T" });
773     /**
774      * 3.8. Adenine or thymine or cytosine: H
775      * 
776      * Not-G is the most simple means of memorising this combination and symbols
777      * logically related to G were examined. F and H would both be suitable, as
778      * the letters before and after G in the alphabet, but A would have no
779      * equivalent to F. The use of H has historical precedence [2].
780      */
781     ambiguityCodes.put("H", new String[]
782     { "A", "T", "C" });
783     /**
784      * 3.9. Guanine or cytosine or thymine: B
785      * 
786      * Not-A as above (section 3.8).
787      */
788     ambiguityCodes.put("B", new String[]
789     { "G", "T", "C" });
790     /**
791      * 3.10. Guanine or adenine or cytosine: V
792      * 
793      * Not-T by analogy with not-G (section 3.8) would be U but this is ruled
794      * out to eliminate confusion with uracil. V is the next logical choice.
795      * Note that T and U may in some cases be considered to be synonyms.
796      */
797     ambiguityCodes.put("V", new String[]
798     { "G", "A", "C" });
799     /**
800      * 3.11. Guanine or adenine or thymine: D
801      * 
802      * Not-C as above (section 3.8).
803      */
804     ambiguityCodes.put("D", new String[]
805     { "G", "A", "T" });
806     /**
807      * 3.12. Guanine or adenine or thymine or cytosine: N
808      */
809     ambiguityCodes.put("R", new String[]
810     { "G", "A", "T", "C" });
811     // Now build codon translation table
812     codonHash2.put("AAA", "K");
813     codonHash2.put("AAG", "K");
814     codonHash2.put("AAC", "N");
815     codonHash2.put("AAT", "N");
816
817     codonHash2.put("CAA", "Q");
818     codonHash2.put("CAG", "Q");
819     codonHash2.put("CAC", "H");
820     codonHash2.put("CAT", "H");
821
822     codonHash2.put("GAA", "E");
823     codonHash2.put("GAG", "E");
824     codonHash2.put("GAC", "D");
825     codonHash2.put("GAT", "D");
826
827     codonHash2.put("TAC", "Y");
828     codonHash2.put("TAT", "Y");
829
830     codonHash2.put("ACA", "T");
831     codonHash2.put("ACC", "T");
832     codonHash2.put("ACT", "T");
833     codonHash2.put("ACG", "T");
834
835     codonHash2.put("CCA", "P");
836     codonHash2.put("CCG", "P");
837     codonHash2.put("CCC", "P");
838     codonHash2.put("CCT", "P");
839
840     codonHash2.put("GCA", "A");
841     codonHash2.put("GCG", "A");
842     codonHash2.put("GCC", "A");
843     codonHash2.put("GCT", "A");
844
845     codonHash2.put("TCA", "S");
846     codonHash2.put("TCG", "S");
847     codonHash2.put("TCC", "S");
848     codonHash2.put("TCT", "S");
849     codonHash2.put("AGC", "S");
850     codonHash2.put("AGT", "S");
851
852     codonHash2.put("AGA", "R");
853     codonHash2.put("AGG", "R");
854     codonHash2.put("CGA", "R");
855     codonHash2.put("CGG", "R");
856     codonHash2.put("CGC", "R");
857     codonHash2.put("CGT", "R");
858
859     codonHash2.put("GGA", "G");
860     codonHash2.put("GGG", "G");
861     codonHash2.put("GGC", "G");
862     codonHash2.put("GGT", "G");
863
864     codonHash2.put("TGA", "*");
865     codonHash2.put("TAA", "*");
866     codonHash2.put("TAG", "*");
867
868     codonHash2.put("TGG", "W");
869
870     codonHash2.put("TGC", "C");
871     codonHash2.put("TGT", "C");
872
873     codonHash2.put("ATA", "I");
874     codonHash2.put("ATC", "I");
875     codonHash2.put("ATT", "I");
876
877     codonHash2.put("ATG", "M");
878
879     codonHash2.put("CTA", "L");
880     codonHash2.put("CTG", "L");
881     codonHash2.put("CTC", "L");
882     codonHash2.put("CTT", "L");
883     codonHash2.put("TTA", "L");
884     codonHash2.put("TTG", "L");
885
886     codonHash2.put("GTA", "V");
887     codonHash2.put("GTG", "V");
888     codonHash2.put("GTC", "V");
889     codonHash2.put("GTT", "V");
890
891     codonHash2.put("TTC", "F");
892     codonHash2.put("TTT", "F");
893     
894     buildAmbiguityCodonSet();
895   }
896   
897   /**
898    * programmatic generation of codons including ambiguity codes
899    */
900   public static void buildAmbiguityCodonSet()
901   {
902     if (_ambiguityCodes.size() > 0)
903     {
904       System.err
905               .println("Ignoring multiple calls to buildAmbiguityCodonSet");
906       return;
907     }
908     // Invert the ambiguity code set
909     for (Map.Entry<String, String[]> acode : ambiguityCodes.entrySet())
910     {
911       for (String r : acode.getValue())
912       {
913         List<String> codesfor = _ambiguityCodes.get(r);
914         if (codesfor == null)
915         {
916           _ambiguityCodes.put(r, codesfor = new ArrayList<String>());
917         }
918         if (!codesfor.contains(acode.getKey()))
919         {
920           codesfor.add(acode.getKey());
921         }
922         else
923         {
924           System.err
925                   .println("Inconsistency in the IUBMB ambiguity code nomenclature table: collision for "
926                           + acode.getKey() + " in residue " + r);
927         }
928       }
929     }
930     // and programmatically add in the ambiguity codes that yield the same amino
931     // acid
932     String[] unambcodons = codonHash2.keySet().toArray(new String[codonHash2.size()]);
933     for (String codon : unambcodons)
934     {
935       String residue = codonHash2.get(codon);
936       String acodon[][] = new String[codon.length()][];
937       for (int i = 0, iSize = codon.length(); i < iSize; i++)
938       {
939         String _ac = "" + codon.charAt(i);
940         List<String> acodes = _ambiguityCodes.get(_ac);
941         if (acodes != null)
942         {
943           acodon[i] = acodes.toArray(new String[acodes.size()]);
944         }
945         else
946         {
947           acodon[i] = new String[]
948           {};
949         }
950       }
951       // enumerate all combinations and test for veracity of translation
952       int tpos[] = new int[codon.length()], cpos[] = new int[codon.length()];
953       for (int i = 0; i < tpos.length; i++)
954       {
955         tpos[i] = -1;
956       }
957       tpos[acodon.length - 1] = 0;
958       int ipos, j;
959       while (tpos[0] < acodon[0].length)
960       {
961         // make all codons for this combination
962         char allres[][] = new char[tpos.length][];
963         String _acodon = "";
964         char _anuc;
965         for (ipos = 0; ipos < tpos.length; ipos++)
966         {
967           if (acodon[ipos].length==0 || tpos[ipos] < 0)
968           {
969             _acodon += codon.charAt(ipos);
970             allres[ipos] = new char[]
971             { codon.charAt(ipos) };
972           }
973           else
974           {
975             _acodon += acodon[ipos][tpos[ipos]];
976             String[] altbase = ambiguityCodes.get(acodon[ipos][tpos[ipos]]);
977             allres[ipos] = new char[altbase.length];
978             j = 0;
979             for (String ab : altbase)
980             {
981               allres[ipos][j++] = ab.charAt(0);
982             }
983           }
984         }
985         // test all codons for this combination
986         for (ipos = 0; ipos < cpos.length; ipos++)
987         {
988           cpos[ipos] = 0;
989         }
990         boolean valid = true;
991         do
992         {
993           String _codon = "";
994           for (j = 0; j < cpos.length; j++)
995           {
996             _codon += allres[j][cpos[j]];
997           }
998           String tr = codonHash2.get(_codon);
999           if (valid = (tr!=null && tr.equals(residue)))
1000           {
1001             // advance to next combination
1002             ipos = acodon.length - 1;
1003             while (++cpos[ipos] >= allres[ipos].length && ipos > 0)
1004             {
1005               cpos[ipos] = 0;
1006               ipos--;
1007             }
1008           }
1009         } while (valid && cpos[0] < allres[0].length);
1010         if (valid)
1011         {
1012           // Add this to the set of codons we will translate
1013 //          System.out.println("Adding ambiguity codon: " + _acodon + " for "
1014 //                  + residue);
1015           codonHash2.put(_acodon, residue);
1016         }
1017         else
1018         {
1019 //          System.err.println("Rejecting ambiguity codon: " + _acodon
1020 //                  + " for " + residue);
1021         }
1022         // next combination
1023         ipos = acodon.length - 1;
1024         while (++tpos[ipos] >= acodon[ipos].length && ipos > 0)
1025         {
1026           tpos[ipos] = -1;
1027           ipos--;
1028         }
1029       }
1030     }
1031
1032   }
1033
1034   static
1035   {
1036     Lys.addElement("AAA");
1037     Lys.addElement("AAG");
1038     Asn.addElement("AAC");
1039     Asn.addElement("AAT");
1040
1041     Gln.addElement("CAA");
1042     Gln.addElement("CAG");
1043     His.addElement("CAC");
1044     His.addElement("CAT");
1045
1046     Glu.addElement("GAA");
1047     Glu.addElement("GAG");
1048     Asp.addElement("GAC");
1049     Asp.addElement("GAT");
1050
1051     Tyr.addElement("TAC");
1052     Tyr.addElement("TAT");
1053
1054     Thr.addElement("ACA");
1055     Thr.addElement("ACG");
1056     Thr.addElement("ACC");
1057     Thr.addElement("ACT");
1058
1059     Pro.addElement("CCA");
1060     Pro.addElement("CCG");
1061     Pro.addElement("CCC");
1062     Pro.addElement("CCT");
1063
1064     Ala.addElement("GCA");
1065     Ala.addElement("GCG");
1066     Ala.addElement("GCC");
1067     Ala.addElement("GCT");
1068
1069     Ser.addElement("TCA");
1070     Ser.addElement("TCG");
1071     Ser.addElement("TCC");
1072     Ser.addElement("TCT");
1073     Ser.addElement("AGC");
1074     Ser.addElement("AGT");
1075
1076     Arg.addElement("AGA");
1077     Arg.addElement("AGG");
1078     Arg.addElement("CGA");
1079     Arg.addElement("CGG");
1080     Arg.addElement("CGC");
1081     Arg.addElement("CGT");
1082
1083     Gly.addElement("GGA");
1084     Gly.addElement("GGG");
1085     Gly.addElement("GGC");
1086     Gly.addElement("GGT");
1087
1088     STOP.addElement("TGA");
1089     STOP.addElement("TAA");
1090     STOP.addElement("TAG");
1091
1092     Trp.addElement("TGG");
1093
1094     Cys.addElement("TGC");
1095     Cys.addElement("TGT");
1096
1097     Ile.addElement("ATA");
1098     Ile.addElement("ATC");
1099     Ile.addElement("ATT");
1100
1101     Met.addElement("ATG");
1102
1103     Leu.addElement("CTA");
1104     Leu.addElement("CTG");
1105     Leu.addElement("CTC");
1106     Leu.addElement("CTT");
1107     Leu.addElement("TTA");
1108     Leu.addElement("TTG");
1109
1110     Val.addElement("GTA");
1111     Val.addElement("GTG");
1112     Val.addElement("GTC");
1113     Val.addElement("GTT");
1114
1115     Phe.addElement("TTC");
1116     Phe.addElement("TTT");
1117   }
1118
1119   // Stores residue codes/names and colours and other things
1120   public static Hashtable propHash = new Hashtable();
1121
1122   public static Hashtable hydrophobic = new Hashtable();
1123
1124   public static Hashtable polar = new Hashtable();
1125
1126   public static Hashtable small = new Hashtable();
1127
1128   public static Hashtable positive = new Hashtable();
1129
1130   public static Hashtable negative = new Hashtable();
1131
1132   public static Hashtable charged = new Hashtable();
1133
1134   public static Hashtable aromatic = new Hashtable();
1135
1136   public static Hashtable aliphatic = new Hashtable();
1137
1138   public static Hashtable tiny = new Hashtable();
1139
1140   public static Hashtable proline = new Hashtable();
1141
1142   static
1143   {
1144     hydrophobic.put("I", new Integer(1));
1145     hydrophobic.put("L", new Integer(1));
1146     hydrophobic.put("V", new Integer(1));
1147     hydrophobic.put("C", new Integer(1));
1148     hydrophobic.put("A", new Integer(1));
1149     hydrophobic.put("G", new Integer(1));
1150     hydrophobic.put("M", new Integer(1));
1151     hydrophobic.put("F", new Integer(1));
1152     hydrophobic.put("Y", new Integer(1));
1153     hydrophobic.put("W", new Integer(1));
1154     hydrophobic.put("H", new Integer(1));
1155     hydrophobic.put("K", new Integer(1));
1156     hydrophobic.put("X", new Integer(1));
1157     hydrophobic.put("-", new Integer(1));
1158     hydrophobic.put("*", new Integer(1));
1159     hydrophobic.put("R", new Integer(0));
1160     hydrophobic.put("E", new Integer(0));
1161     hydrophobic.put("Q", new Integer(0));
1162     hydrophobic.put("D", new Integer(0));
1163     hydrophobic.put("N", new Integer(0));
1164     hydrophobic.put("S", new Integer(0));
1165     hydrophobic.put("T", new Integer(0));
1166     hydrophobic.put("P", new Integer(0));
1167   }
1168
1169   static
1170   {
1171     polar.put("Y", new Integer(1));
1172     polar.put("W", new Integer(1));
1173     polar.put("H", new Integer(1));
1174     polar.put("K", new Integer(1));
1175     polar.put("R", new Integer(1));
1176     polar.put("E", new Integer(1));
1177     polar.put("Q", new Integer(1));
1178     polar.put("D", new Integer(1));
1179     polar.put("N", new Integer(1));
1180     polar.put("S", new Integer(1));
1181     polar.put("T", new Integer(1));
1182     polar.put("X", new Integer(1));
1183     polar.put("-", new Integer(1));
1184     polar.put("*", new Integer(1));
1185     polar.put("I", new Integer(0));
1186     polar.put("L", new Integer(0));
1187     polar.put("V", new Integer(0));
1188     polar.put("C", new Integer(0));
1189     polar.put("A", new Integer(0));
1190     polar.put("G", new Integer(0));
1191     polar.put("M", new Integer(0));
1192     polar.put("F", new Integer(0));
1193     polar.put("P", new Integer(0));
1194   }
1195
1196   static
1197   {
1198     small.put("I", new Integer(0));
1199     small.put("L", new Integer(0));
1200     small.put("V", new Integer(1));
1201     small.put("C", new Integer(1));
1202     small.put("A", new Integer(1));
1203     small.put("G", new Integer(1));
1204     small.put("M", new Integer(0));
1205     small.put("F", new Integer(0));
1206     small.put("Y", new Integer(0));
1207     small.put("W", new Integer(0));
1208     small.put("H", new Integer(0));
1209     small.put("K", new Integer(0));
1210     small.put("R", new Integer(0));
1211     small.put("E", new Integer(0));
1212     small.put("Q", new Integer(0));
1213     small.put("D", new Integer(1));
1214     small.put("N", new Integer(1));
1215     small.put("S", new Integer(1));
1216     small.put("T", new Integer(1));
1217     small.put("P", new Integer(1));
1218     small.put("-", new Integer(1));
1219     small.put("*", new Integer(1));
1220   }
1221
1222   static
1223   {
1224     positive.put("I", new Integer(0));
1225     positive.put("L", new Integer(0));
1226     positive.put("V", new Integer(0));
1227     positive.put("C", new Integer(0));
1228     positive.put("A", new Integer(0));
1229     positive.put("G", new Integer(0));
1230     positive.put("M", new Integer(0));
1231     positive.put("F", new Integer(0));
1232     positive.put("Y", new Integer(0));
1233     positive.put("W", new Integer(0));
1234     positive.put("H", new Integer(1));
1235     positive.put("K", new Integer(1));
1236     positive.put("R", new Integer(1));
1237     positive.put("E", new Integer(0));
1238     positive.put("Q", new Integer(0));
1239     positive.put("D", new Integer(0));
1240     positive.put("N", new Integer(0));
1241     positive.put("S", new Integer(0));
1242     positive.put("T", new Integer(0));
1243     positive.put("P", new Integer(0));
1244     positive.put("-", new Integer(1));
1245     positive.put("*", new Integer(1));
1246   }
1247
1248   static
1249   {
1250     negative.put("I", new Integer(0));
1251     negative.put("L", new Integer(0));
1252     negative.put("V", new Integer(0));
1253     negative.put("C", new Integer(0));
1254     negative.put("A", new Integer(0));
1255     negative.put("G", new Integer(0));
1256     negative.put("M", new Integer(0));
1257     negative.put("F", new Integer(0));
1258     negative.put("Y", new Integer(0));
1259     negative.put("W", new Integer(0));
1260     negative.put("H", new Integer(0));
1261     negative.put("K", new Integer(0));
1262     negative.put("R", new Integer(0));
1263     negative.put("E", new Integer(1));
1264     negative.put("Q", new Integer(0));
1265     negative.put("D", new Integer(1));
1266     negative.put("N", new Integer(0));
1267     negative.put("S", new Integer(0));
1268     negative.put("T", new Integer(0));
1269     negative.put("P", new Integer(0));
1270     negative.put("-", new Integer(1));
1271     negative.put("*", new Integer(1));
1272   }
1273
1274   static
1275   {
1276     charged.put("I", new Integer(0));
1277     charged.put("L", new Integer(0));
1278     charged.put("V", new Integer(0));
1279     charged.put("C", new Integer(0));
1280     charged.put("A", new Integer(0));
1281     charged.put("G", new Integer(0));
1282     charged.put("M", new Integer(0));
1283     charged.put("F", new Integer(0));
1284     charged.put("Y", new Integer(0));
1285     charged.put("W", new Integer(0));
1286     charged.put("H", new Integer(1));
1287     charged.put("K", new Integer(1));
1288     charged.put("R", new Integer(1));
1289     charged.put("E", new Integer(1));
1290     charged.put("Q", new Integer(0));
1291     charged.put("D", new Integer(1));
1292     charged.put("N", new Integer(0)); // Asparagine is polar but not charged.
1293                                       // Alternative would be charged and
1294                                       // negative (in basic form)?
1295     charged.put("S", new Integer(0));
1296     charged.put("T", new Integer(0));
1297     charged.put("P", new Integer(0));
1298     charged.put("-", new Integer(1));
1299     charged.put("*", new Integer(1));
1300   }
1301
1302   static
1303   {
1304     aromatic.put("I", new Integer(0));
1305     aromatic.put("L", new Integer(0));
1306     aromatic.put("V", new Integer(0));
1307     aromatic.put("C", new Integer(0));
1308     aromatic.put("A", new Integer(0));
1309     aromatic.put("G", new Integer(0));
1310     aromatic.put("M", new Integer(0));
1311     aromatic.put("F", new Integer(1));
1312     aromatic.put("Y", new Integer(1));
1313     aromatic.put("W", new Integer(1));
1314     aromatic.put("H", new Integer(1));
1315     aromatic.put("K", new Integer(0));
1316     aromatic.put("R", new Integer(0));
1317     aromatic.put("E", new Integer(0));
1318     aromatic.put("Q", new Integer(0));
1319     aromatic.put("D", new Integer(0));
1320     aromatic.put("N", new Integer(0));
1321     aromatic.put("S", new Integer(0));
1322     aromatic.put("T", new Integer(0));
1323     aromatic.put("P", new Integer(0));
1324     aromatic.put("-", new Integer(1));
1325     aromatic.put("*", new Integer(1));
1326   }
1327
1328   static
1329   {
1330     aliphatic.put("I", new Integer(1));
1331     aliphatic.put("L", new Integer(1));
1332     aliphatic.put("V", new Integer(1));
1333     aliphatic.put("C", new Integer(0));
1334     aliphatic.put("A", new Integer(0));
1335     aliphatic.put("G", new Integer(0));
1336     aliphatic.put("M", new Integer(0));
1337     aliphatic.put("F", new Integer(0));
1338     aliphatic.put("Y", new Integer(0));
1339     aliphatic.put("W", new Integer(0));
1340     aliphatic.put("H", new Integer(0));
1341     aliphatic.put("K", new Integer(0));
1342     aliphatic.put("R", new Integer(0));
1343     aliphatic.put("E", new Integer(0));
1344     aliphatic.put("Q", new Integer(0));
1345     aliphatic.put("D", new Integer(0));
1346     aliphatic.put("N", new Integer(0));
1347     aliphatic.put("S", new Integer(0));
1348     aliphatic.put("T", new Integer(0));
1349     aliphatic.put("P", new Integer(0));
1350     aliphatic.put("-", new Integer(1));
1351     aliphatic.put("*", new Integer(1));
1352   }
1353
1354   static
1355   {
1356     tiny.put("I", new Integer(0));
1357     tiny.put("L", new Integer(0));
1358     tiny.put("V", new Integer(0));
1359     tiny.put("C", new Integer(0));
1360     tiny.put("A", new Integer(1));
1361     tiny.put("G", new Integer(1));
1362     tiny.put("M", new Integer(0));
1363     tiny.put("F", new Integer(0));
1364     tiny.put("Y", new Integer(0));
1365     tiny.put("W", new Integer(0));
1366     tiny.put("H", new Integer(0));
1367     tiny.put("K", new Integer(0));
1368     tiny.put("R", new Integer(0));
1369     tiny.put("E", new Integer(0));
1370     tiny.put("Q", new Integer(0));
1371     tiny.put("D", new Integer(0));
1372     tiny.put("N", new Integer(0));
1373     tiny.put("S", new Integer(1));
1374     tiny.put("T", new Integer(0));
1375     tiny.put("P", new Integer(0));
1376     tiny.put("-", new Integer(1));
1377     tiny.put("*", new Integer(1));
1378   }
1379
1380   static
1381   {
1382     proline.put("I", new Integer(0));
1383     proline.put("L", new Integer(0));
1384     proline.put("V", new Integer(0));
1385     proline.put("C", new Integer(0));
1386     proline.put("A", new Integer(0));
1387     proline.put("G", new Integer(0));
1388     proline.put("M", new Integer(0));
1389     proline.put("F", new Integer(0));
1390     proline.put("Y", new Integer(0));
1391     proline.put("W", new Integer(0));
1392     proline.put("H", new Integer(0));
1393     proline.put("K", new Integer(0));
1394     proline.put("R", new Integer(0));
1395     proline.put("E", new Integer(0));
1396     proline.put("Q", new Integer(0));
1397     proline.put("D", new Integer(0));
1398     proline.put("N", new Integer(0));
1399     proline.put("S", new Integer(0));
1400     proline.put("T", new Integer(0));
1401     proline.put("P", new Integer(1));
1402     proline.put("-", new Integer(1));
1403     proline.put("*", new Integer(1));
1404   }
1405
1406   static
1407   {
1408     propHash.put("hydrophobic", hydrophobic);
1409     propHash.put("small", small);
1410     propHash.put("positive", positive);
1411     propHash.put("negative", negative);
1412     propHash.put("charged", charged);
1413     propHash.put("aromatic", aromatic);
1414     propHash.put("aliphatic", aliphatic);
1415     propHash.put("tiny", tiny);
1416     propHash.put("proline", proline);
1417     propHash.put("polar", polar);
1418   }
1419
1420   private ResidueProperties()
1421   {
1422   }
1423
1424   public static double getHydmax()
1425   {
1426     return hydmax;
1427   }
1428
1429   public static double getHydmin()
1430   {
1431     return hydmin;
1432   }
1433
1434   public static double[] getHyd()
1435   {
1436     return hyd;
1437   }
1438
1439   public static Hashtable getAA3Hash()
1440   {
1441     return aa3Hash;
1442   }
1443
1444   public static int[][] getDNA()
1445   {
1446     return ResidueProperties.DNA;
1447   }
1448
1449   public static int[][] getBLOSUM62()
1450   {
1451     return ResidueProperties.BLOSUM62;
1452   }
1453
1454   public static int getPAM250(String A1, String A2)
1455   {
1456     return getPAM250(A1.charAt(0), A2.charAt(0));
1457   }
1458
1459   public static int getBLOSUM62(char c1, char c2)
1460   {
1461     int pog = 0;
1462
1463     try
1464     {
1465       int a = aaIndex[c1];
1466       int b = aaIndex[c2];
1467
1468       pog = ResidueProperties.BLOSUM62[a][b];
1469     } catch (Exception e)
1470     {
1471       // System.out.println("Unknown residue in " + A1 + " " + A2);
1472     }
1473
1474     return pog;
1475   }
1476
1477   public static Vector getCodons(String res)
1478   {
1479     if (codonHash.containsKey(res))
1480     {
1481       return (Vector) codonHash.get(res);
1482     }
1483
1484     return null;
1485   }
1486
1487   public static String codonTranslate(String lccodon)
1488   {
1489     if (false)
1490     {
1491       return _codonTranslate(lccodon);
1492     }
1493     String cdn = codonHash2.get(lccodon.toUpperCase());
1494     if (cdn!=null && cdn.equals("*"))
1495     {
1496       return "STOP";
1497     }
1498     return cdn;
1499   }
1500   public static String _codonTranslate(String lccodon)
1501   {
1502     String codon = lccodon.toUpperCase();
1503     // all base ambiguity codes yield an 'X' amino acid residue
1504     if (codon.indexOf('X') > -1 || codon.indexOf('N') > -1)
1505     {
1506       return "X";
1507     }
1508     Enumeration e = codonHash.keys();
1509
1510     while (e.hasMoreElements())
1511     {
1512       String key = (String) e.nextElement();
1513       Vector tmp = (Vector) codonHash.get(key);
1514
1515       if (tmp.contains(codon))
1516       {
1517         return key;
1518       }
1519     }
1520
1521     return null;
1522   }
1523
1524   public static int[][] getDefaultPeptideMatrix()
1525   {
1526     return ResidueProperties.getBLOSUM62();
1527   }
1528
1529   public static int[][] getDefaultDnaMatrix()
1530   {
1531     return ResidueProperties.getDNA();
1532   }
1533
1534   /**
1535    * get a ScoreMatrix based on its string name
1536    * 
1537    * @param pwtype
1538    * @return matrix in scoreMatrices with key pwtype or null
1539    */
1540   public static ScoreMatrix getScoreMatrix(String pwtype)
1541   {
1542     Object val = scoreMatrices.get(pwtype);
1543     if (val != null)
1544     {
1545       return (ScoreMatrix) val;
1546     }
1547     return null;
1548   }
1549
1550   public static int getPAM250(char c, char d)
1551   {
1552     int a = aaIndex[c];
1553     int b = aaIndex[d];
1554
1555     int pog = ResidueProperties.PAM250[a][b];
1556
1557     return pog;
1558   }
1559
1560   public static Hashtable toDssp3State;
1561   static
1562   {
1563     toDssp3State = new Hashtable();
1564     toDssp3State.put("H", "H");
1565     toDssp3State.put("E", "E");
1566     toDssp3State.put("C", " ");
1567     toDssp3State.put(" ", " ");
1568     toDssp3State.put("T", " ");
1569     toDssp3State.put("B", "E");
1570     toDssp3State.put("G", "H");
1571     toDssp3State.put("I", "H");
1572     toDssp3State.put("X", " ");
1573   }
1574
1575   /**
1576    * translate from other dssp secondary structure alphabets to 3-state
1577    * 
1578    * @param ssstring
1579    * @return ssstring as a three-state secondary structure assignment.
1580    */
1581   public static String getDssp3state(String ssstring)
1582   {
1583     if (ssstring == null)
1584     {
1585       return null;
1586     }
1587     StringBuffer ss = new StringBuffer();
1588     for (int i = 0; i < ssstring.length(); i++)
1589     {
1590       String ssc = ssstring.substring(i, i + 1);
1591       if (toDssp3State.containsKey(ssc))
1592       {
1593         ss.append((String) toDssp3State.get(ssc));
1594       }
1595       else
1596       {
1597         ss.append(" ");
1598       }
1599     }
1600     return ss.toString();
1601   }
1602
1603   /**
1604    * Used by getRNASecStrucState
1605    * 
1606    */
1607   public static Hashtable toRNAssState;
1608   static
1609   {
1610     toRNAssState = new Hashtable();
1611     toRNAssState.put(")", "S");
1612     toRNAssState.put("(", "S");
1613   }
1614
1615   /**
1616    * translate to RNA secondary structure representation
1617    * 
1618    * @param ssstring
1619    * @return ssstring as a RNA-state secondary structure assignment.
1620    */
1621   public static String getRNASecStrucState(String ssstring)
1622   {
1623     if (ssstring == null)
1624     {
1625       return null;
1626     }
1627     StringBuffer ss = new StringBuffer();
1628     for (int i = 0; i < ssstring.length(); i++)
1629     {
1630       String ssc = ssstring.substring(i, i + 1);
1631       if (toRNAssState.containsKey(ssc))
1632       {
1633         ss.append((String) toRNAssState.get(ssc));
1634       }
1635       else
1636       {
1637         ss.append(" ");
1638       }
1639     }
1640     return ss.toString();
1641   }
1642
1643   // main method generates perl representation of residue property hash
1644   // / cut here
1645   public static void main(String[] args)
1646   {
1647     Hashtable aa = new Hashtable();
1648     System.out.println("my %aa = {");
1649     // invert property hashes
1650     Enumeration prop = propHash.keys();
1651     while (prop.hasMoreElements())
1652     {
1653       String pname = (String) prop.nextElement();
1654       Hashtable phash = (Hashtable) propHash.get(pname);
1655       Enumeration res = phash.keys();
1656       while (res.hasMoreElements())
1657       {
1658         String rname = (String) res.nextElement();
1659         Vector aprops = (Vector) aa.get(rname);
1660         if (aprops == null)
1661         {
1662           aprops = new Vector();
1663           aa.put(rname, aprops);
1664         }
1665         Integer hasprop = (Integer) phash.get(rname);
1666         if (hasprop.intValue() == 1)
1667         {
1668           aprops.addElement(pname);
1669         }
1670       }
1671     }
1672     Enumeration res = aa.keys();
1673     while (res.hasMoreElements())
1674     {
1675       String rname = (String) res.nextElement();
1676
1677       System.out.print("'" + rname + "' => [");
1678       Enumeration props = ((Vector) aa.get(rname)).elements();
1679       while (props.hasMoreElements())
1680       {
1681         System.out.print("'" + (String) props.nextElement() + "'");
1682         if (props.hasMoreElements())
1683         {
1684           System.out.println(", ");
1685         }
1686       }
1687       System.out.println("]" + (res.hasMoreElements() ? "," : ""));
1688     }
1689     System.out.println("};");
1690   }
1691   // to here
1692 }