JAL-2365 test for lightgray, darkgray not lightGray, darkGray
[jalview.git] / src / jalview / schemes / ColourSchemeProperty.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ 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
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.schemes;
22
23 import jalview.datamodel.AnnotatedCollectionI;
24
25 import java.awt.Color;
26
27 /**
28  * ColourSchemeProperty binds names to hardwired colourschemes and tries to deal
29  * intelligently with mapping unknown names to user defined colourschemes (that
30  * exist or can be created from the string representation of the colourscheme
31  * name - either a hex RGB triplet or a named colour under java.awt.color ). The
32  * values of the colourscheme constants is important for callers of
33  * getColourName(int i), since it can be used to enumerate the set of built in
34  * colours. The FIRST_COLOUR and LAST_COLOUR symbols are provided for this.
35  * 
36  * @author $author$
37  * @version $Revision$
38  */
39 public class ColourSchemeProperty
40 {
41   /** Undefined Colourscheme Index */
42   public static final int UNDEFINED = -1;
43
44   /** for schemes defined on the fly */
45   public static final int USER_DEFINED = 0;
46
47   /** No Colourscheme Index */
48   public static final int NONE = 1;
49
50   /** DOCUMENT ME!! */
51   public static final int CLUSTAL = 2;
52
53   /** DOCUMENT ME!! */
54   public static final int BLOSUM = 3;
55
56   /** DOCUMENT ME!! */
57   public static final int PID = 4;
58
59   /** DOCUMENT ME!! */
60   public static final int ZAPPO = 5;
61
62   /** DOCUMENT ME!! */
63   public static final int TAYLOR = 6;
64
65   /** DOCUMENT ME!! */
66   public static final int HYDROPHOBIC = 7;
67
68   /** DOCUMENT ME!! */
69   public static final int HELIX = 8;
70
71   /** DOCUMENT ME!! */
72   public static final int STRAND = 9;
73
74   /** DOCUMENT ME!! */
75   public static final int TURN = 10;
76
77   /** DOCUMENT ME!! */
78   public static final int BURIED = 11;
79
80   /** DOCUMENT ME!! */
81   public static final int NUCLEOTIDE = 12;
82
83   /**
84    * purine/pyrimidine
85    */
86   public static final int PURINEPYRIMIDINE = 13;
87
88   public static final int COVARIATION = 14;
89
90   public static final int TCOFFEE = 15;
91
92   public static final int RNAHELIX = 16;
93
94   public static final int RNAINTERACTION = 17;
95
96   /**
97    * index of first colourscheme (includes 'None')
98    */
99   public static final int FIRST_COLOUR = NONE;
100
101   public static final int LAST_COLOUR = RNAINTERACTION;
102
103   /**
104    * DOCUMENT ME!
105    * 
106    * @param name
107    *          DOCUMENT ME!
108    * 
109    * @return DOCUMENT ME!
110    */
111   public static int getColourIndexFromName(String name)
112   {
113     int ret = UNDEFINED;
114
115     if (name.equalsIgnoreCase("Clustal"))
116     {
117       ret = CLUSTAL;
118     }
119     else if (name.equalsIgnoreCase("Blosum62"))
120     {
121       ret = BLOSUM;
122     }
123     else if (name.equalsIgnoreCase("% Identity"))
124     {
125       ret = PID;
126     }
127     else if (name.equalsIgnoreCase("Zappo"))
128     {
129       ret = ZAPPO;
130     }
131     else if (name.equalsIgnoreCase("Taylor"))
132     {
133       ret = TAYLOR;
134     }
135     else if (name.equalsIgnoreCase("Hydrophobic"))
136     {
137       ret = HYDROPHOBIC;
138     }
139     else if (name.equalsIgnoreCase("Helix Propensity"))
140     {
141       ret = HELIX;
142     }
143     else if (name.equalsIgnoreCase("Strand Propensity"))
144     {
145       ret = STRAND;
146     }
147     else if (name.equalsIgnoreCase("Turn Propensity"))
148     {
149       ret = TURN;
150     }
151     else if (name.equalsIgnoreCase("Buried Index"))
152     {
153       ret = BURIED;
154     }
155     else if (name.equalsIgnoreCase("Nucleotide"))
156     {
157       ret = NUCLEOTIDE;
158     }
159     else if (name.equalsIgnoreCase("T-Coffee Scores"))
160     {
161       ret = TCOFFEE;
162     }
163
164     else if (name.equalsIgnoreCase("User Defined"))
165     {
166       ret = USER_DEFINED;
167     }
168     else if (name.equalsIgnoreCase("None"))
169     {
170       ret = NONE;
171     }
172     else if (name.equalsIgnoreCase("Purine/Pyrimidine"))
173     {
174       ret = PURINEPYRIMIDINE;
175     }
176     else if (name.equalsIgnoreCase("RNA Interaction type"))
177     {
178       ret = RNAINTERACTION;
179     }
180     else if (name.equalsIgnoreCase("RNA Helices"))
181     {
182       ret = RNAHELIX;
183     }
184     // else if (name.equalsIgnoreCase("Covariation"))
185     // {
186     // ret = COVARIATION;
187     // }
188
189     return ret;
190   }
191
192   /**
193    * DOCUMENT ME!
194    * 
195    * @param cs
196    *          DOCUMENT ME!
197    * 
198    * @return DOCUMENT ME!
199    */
200   public static String getColourName(ColourSchemeI cs)
201   {
202
203     int index = NONE;
204
205     if (cs instanceof ClustalxColourScheme)
206     {
207       index = CLUSTAL;
208     }
209     else if (cs instanceof Blosum62ColourScheme)
210     {
211       index = BLOSUM;
212     }
213     else if (cs instanceof PIDColourScheme)
214     {
215       index = PID;
216     }
217     else if (cs instanceof ZappoColourScheme)
218     {
219       index = ZAPPO;
220     }
221     else if (cs instanceof TaylorColourScheme)
222     {
223       index = TAYLOR;
224     }
225     else if (cs instanceof HydrophobicColourScheme)
226     {
227       index = HYDROPHOBIC;
228     }
229     else if (cs instanceof HelixColourScheme)
230     {
231       index = HELIX;
232     }
233     else if (cs instanceof StrandColourScheme)
234     {
235       index = STRAND;
236     }
237     else if (cs instanceof TurnColourScheme)
238     {
239       index = TURN;
240     }
241     else if (cs instanceof BuriedColourScheme)
242     {
243       index = BURIED;
244     }
245     else if (cs instanceof NucleotideColourScheme)
246     {
247       index = NUCLEOTIDE;
248     }
249     else if (cs instanceof PurinePyrimidineColourScheme)
250     {
251       index = PURINEPYRIMIDINE;
252     }
253     else if (cs instanceof TCoffeeColourScheme)
254     {
255       index = TCOFFEE;
256     }
257     else if (cs instanceof RNAHelicesColour)
258     {
259       index = RNAHELIX;
260     }
261     /*
262      * else if (cs instanceof CovariationColourScheme) { index = COVARIATION; }
263      */
264     else if (cs instanceof UserColourScheme)
265     {
266       if ((((UserColourScheme) cs).getName() != null)
267               && (((UserColourScheme) cs).getName().length() > 0))
268       {
269         return ((UserColourScheme) cs).getName();
270       }
271       // get default colourscheme name
272       index = USER_DEFINED;
273     }
274
275     return getColourName(index);
276   }
277
278   /**
279    * DOCUMENT ME!
280    * 
281    * @param index
282    *          DOCUMENT ME!
283    * 
284    * @return DOCUMENT ME!
285    */
286   public static String getColourName(int index)
287   {
288     String ret = null;
289
290     switch (index)
291     {
292     case CLUSTAL:
293       ret = "Clustal";
294
295       break;
296
297     case BLOSUM:
298       ret = "Blosum62";
299
300       break;
301
302     case PID:
303       ret = "% Identity";
304
305       break;
306
307     case ZAPPO:
308       ret = "Zappo";
309
310       break;
311
312     case TAYLOR:
313       ret = "Taylor";
314       break;
315
316     case HYDROPHOBIC:
317       ret = "Hydrophobic";
318
319       break;
320
321     case HELIX:
322       ret = "Helix Propensity";
323
324       break;
325
326     case STRAND:
327       ret = "Strand Propensity";
328
329       break;
330
331     case TURN:
332       ret = "Turn Propensity";
333
334       break;
335
336     case BURIED:
337       ret = "Buried Index";
338
339       break;
340
341     case NUCLEOTIDE:
342       ret = "Nucleotide";
343
344       break;
345
346     case PURINEPYRIMIDINE:
347       ret = "Purine/Pyrimidine";
348
349       break;
350
351     case TCOFFEE:
352       ret = "T-Coffee Scores";
353
354       break;
355
356     case RNAINTERACTION:
357       ret = "RNA Interaction type";
358
359       break;
360     case RNAHELIX:
361       ret = "RNA Helices";
362
363       break;
364     /*
365      * case COVARIATION: ret = "Covariation";
366      * 
367      * break;
368      */
369     case USER_DEFINED:
370       ret = "User Defined";
371
372       break;
373
374     default:
375       ret = "None";
376
377       break;
378     }
379
380     return ret;
381   }
382
383   /**
384    * retrieve or create colourscheme associated with name
385    * 
386    * @param seqs
387    *          sequences to colour
388    * @param width
389    *          range of sequences to colour
390    * @param name
391    *          colourscheme name, applet colour parameter specification, or
392    *          string to parse as colour for new coloursheme
393    * @return Valid Colourscheme
394    */
395   public static ColourSchemeI getColour(AnnotatedCollectionI alignment,
396           String name)
397   {
398     int colindex = getColourIndexFromName(name);
399     if (colindex == UNDEFINED)
400     {
401       if (name.indexOf('=') == -1)
402       {
403         // try to build a colour from the string directly
404         try
405         {
406           return new UserColourScheme(name);
407         } catch (Exception e)
408         {
409           // System.err.println("Ignoring unknown colourscheme name");
410         }
411       }
412       else
413       {
414         // try to parse the string as a residue colourscheme
415         try
416         {
417           // fix the launchApp user defined coloursheme transfer bug
418           UserColourScheme ucs = new UserColourScheme("white");
419           ucs.parseAppletParameter(name);
420
421         } catch (Exception e)
422         {
423           // System.err.println("Ignoring exception when parsing colourscheme as applet-parameter");
424         }
425       }
426     }
427     return getColour(alignment, colindex);
428   }
429
430   /**
431    * Construct an instance of ColourSchemeI corresponding to the given
432    * colourscheme index
433    * 
434    * @param seqs
435    *          sequences to be coloured by colourscheme
436    * @param width
437    *          geometry of alignment
438    * @param index
439    *          colourscheme number
440    * 
441    * @return null or an instance of the colourscheme configured to colour given
442    *         sequence set
443    */
444   public static ColourSchemeI getColour(
445           jalview.datamodel.AnnotatedCollectionI coll, int index)
446   {
447     // TODO 3.0 2.8 refactor signature to take an alignmentI like container so
448     // colourschemes based on annotation can be initialised
449     ColourSchemeI cs = null;
450
451     switch (index)
452     {
453     case CLUSTAL:
454       cs = new ClustalxColourScheme(coll, null);
455
456       break;
457
458     case BLOSUM:
459       cs = new Blosum62ColourScheme();
460
461       break;
462
463     case PID:
464       cs = new PIDColourScheme();
465
466       break;
467
468     case ZAPPO:
469       cs = new ZappoColourScheme();
470
471       break;
472
473     case TAYLOR:
474       cs = new TaylorColourScheme();
475       break;
476
477     case HYDROPHOBIC:
478       cs = new HydrophobicColourScheme();
479
480       break;
481
482     case HELIX:
483       cs = new HelixColourScheme();
484
485       break;
486
487     case STRAND:
488       cs = new StrandColourScheme();
489
490       break;
491
492     case TURN:
493       cs = new TurnColourScheme();
494
495       break;
496
497     case BURIED:
498       cs = new BuriedColourScheme();
499
500       break;
501
502     case NUCLEOTIDE:
503       cs = new NucleotideColourScheme();
504
505       break;
506
507     case PURINEPYRIMIDINE:
508       cs = new PurinePyrimidineColourScheme();
509
510       break;
511
512     case TCOFFEE:
513       cs = new TCoffeeColourScheme(coll);
514       break;
515
516     case RNAHELIX:
517       cs = new RNAHelicesColour(coll);
518       break;
519
520     // case COVARIATION:
521     // cs = new CovariationColourScheme(annotation);
522     // break;
523
524     case USER_DEFINED:
525       Color[] col = new Color[24];
526       for (int i = 0; i < 24; i++)
527       {
528         col[i] = Color.white;
529       }
530       cs = new UserColourScheme(col);
531       break;
532
533     default:
534       break;
535     }
536
537     return cs;
538   }
539
540   /**
541    * Returns the Color constant for a given colour name e.g. "pink", or null if
542    * the name is not recognised
543    * 
544    * @param name
545    * @return
546    */
547   public static Color getAWTColorFromName(String name)
548   {
549     if (name == null)
550     {
551       return null;
552     }
553     Color col = null;
554     name = name.toLowerCase();
555
556     // or make a static map; or use reflection on the field name
557     switch (name)
558     {
559     case "black":
560       col = Color.black;
561       break;
562     case "blue":
563       col = Color.blue;
564       break;
565     case "cyan":
566       col = Color.cyan;
567       break;
568     case "darkgray":
569       col = Color.darkGray;
570       break;
571     case "gray":
572       col = Color.gray;
573       break;
574     case "green":
575       col = Color.green;
576       break;
577     case "lightgray":
578       col = Color.lightGray;
579       break;
580     case "magenta":
581       col = Color.magenta;
582       break;
583     case "orange":
584       col = Color.orange;
585       break;
586     case "pink":
587       col = Color.pink;
588       break;
589     case "red":
590       col = Color.red;
591       break;
592     case "white":
593       col = Color.white;
594       break;
595     case "yellow":
596       col = Color.yellow;
597       break;
598     }
599
600     return col;
601   }
602
603   public static Color rnaHelices[] = null;
604
605   public static void initRnaHelicesShading(int n)
606   {
607     int j = 0;
608     if (rnaHelices == null)
609     {
610       rnaHelices = new Color[n + 1];
611     }
612     else if (rnaHelices != null && rnaHelices.length <= n)
613     {
614       Color[] t = new Color[n + 1];
615       System.arraycopy(rnaHelices, 0, t, 0, rnaHelices.length);
616       j = rnaHelices.length;
617       rnaHelices = t;
618     }
619     else
620     {
621       return;
622     }
623     // Generate random colors and store
624     for (; j <= n; j++)
625     {
626       rnaHelices[j] = jalview.util.ColorUtils
627               .generateRandomColor(Color.white);
628     }
629   }
630
631   /**
632    * delete the existing cached RNA helces colours
633    */
634   public static void resetRnaHelicesShading()
635   {
636     rnaHelices = null;
637   }
638
639 }