JAL-3148 add findColour(char) to ColourSchemeI
[jalview.git] / src / jalview / schemes / ResidueColourScheme.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 import jalview.datamodel.SequenceCollectionI;
25 import jalview.datamodel.SequenceGroup;
26 import jalview.datamodel.SequenceI;
27
28 import java.awt.Color;
29 import java.util.Map;
30
31 /**
32  * Base class for residue-based colour schemes
33  */
34 public abstract class ResidueColourScheme implements ColourSchemeI
35 {
36   public static final String NONE = "None";
37
38   /*
39    * default display name for a user defined colour scheme
40    */
41   public static final String USER_DEFINED = "User Defined";
42
43   /*
44    * name for (new) "User Defined.." colour scheme menu item
45    */
46   public static final String USER_DEFINED_MENU = "*User Defined*";
47
48   /*
49    * lookup up by character value e.g. 'G' to the colors array index
50    * e.g. if symbolIndex['K'] = 11 then colors[11] is the colour for K
51    */
52   final int[] symbolIndex;
53
54   /*
55    * colour for residue characters as indexed by symbolIndex
56    */
57   Color[] colors = null;
58
59   /* Set when threshold colouring to either pid_gaps or pid_nogaps */
60   protected boolean ignoreGaps = false;
61
62   /**
63    * Creates a new ResidueColourScheme object.
64    * 
65    * @param final
66    *          int[] index table into colors (ResidueProperties.naIndex or
67    *          ResidueProperties.aaIndex)
68    * @param colors
69    *          colours for symbols in sequences
70    */
71   public ResidueColourScheme(int[] aaOrnaIndex, Color[] colours)
72   {
73     symbolIndex = aaOrnaIndex;
74     this.colors = colours;
75   }
76
77   /**
78    * Creates a new ResidueColourScheme object with a lookup table for indexing
79    * the colour map
80    */
81   public ResidueColourScheme(int[] aaOrNaIndex)
82   {
83     symbolIndex = aaOrNaIndex;
84   }
85
86   /**
87    * Creates a new ResidueColourScheme object - default constructor for
88    * non-sequence dependent colourschemes
89    */
90   public ResidueColourScheme()
91   {
92     symbolIndex = null;
93   }
94
95   @Override
96   public Color findColour(char c)
97   {
98     Color colour = Color.white;
99
100     if (colors != null && symbolIndex != null && c < symbolIndex.length
101             && symbolIndex[c] < colors.length)
102     {
103       colour = colors[symbolIndex[c]];
104     }
105
106     return colour;
107   }
108
109   /**
110    * Default is to call the overloaded method that ignores consensus. A colour
111    * scheme that depends on consensus (for example, Blosum62), should override
112    * this method instead.
113    */
114   @Override
115   public Color findColour(char c, int j, SequenceI seq,
116           String consensusResidue, float pid)
117   {
118     return findColour(c, j, seq);
119   }
120
121   /**
122    * Default implementation looks up the residue colour in a fixed scheme, or
123    * returns White if not found. Override this method for a colour scheme that
124    * depends on the column position or sequence.
125    * 
126    * @param c
127    * @param j
128    * @param seq
129    * @return
130    */
131   protected Color findColour(char c, int j, SequenceI seq)
132   {
133     return findColour(c);
134   }
135
136   @Override
137   public void alignmentChanged(AnnotatedCollectionI alignment,
138           Map<SequenceI, SequenceCollectionI> hiddenReps)
139   {
140   }
141
142   /**
143    * Answers false if the colour scheme is nucleotide or peptide specific, and
144    * the data does not match, else true. Override to modify or extend this test
145    * as required.
146    */
147   @Override
148   public boolean isApplicableTo(AnnotatedCollectionI ac)
149   {
150     if (!isPeptideSpecific() && !isNucleotideSpecific())
151     {
152       return true;
153     }
154     if (ac == null)
155     {
156       return true;
157     }
158     /*
159      * pop-up menu on selection group before group created
160      * (no alignment context)
161      */
162     // TODO: add nucleotide flag to SequenceGroup?
163     if (ac instanceof SequenceGroup && ac.getContext() == null)
164     {
165       return true;
166     }
167
168     /*
169      * inspect the data context (alignment) for residue type
170      */
171     boolean nucleotide = ac.isNucleotide();
172
173     /*
174      * does data type match colour scheme type?
175      */
176     return (nucleotide && isNucleotideSpecific())
177             || (!nucleotide && isPeptideSpecific());
178   }
179
180   /**
181    * Answers true if the colour scheme is normally only for peptide data
182    * 
183    * @return
184    */
185   public boolean isPeptideSpecific()
186   {
187     return false;
188   }
189
190   /**
191    * Answers true if the colour scheme is normally only for nucleotide data
192    * 
193    * @return
194    */
195   public boolean isNucleotideSpecific()
196   {
197     return false;
198   }
199
200   /**
201    * Default method returns true. Override this to return false in colour
202    * schemes that are not determined solely by the sequence symbol.
203    */
204   @Override
205   public boolean isSimple()
206   {
207     return true;
208   }
209
210   /**
211    * Default method returns false. Override this to return true in colour
212    * schemes that have a colour associated with gap residues.
213    */
214   @Override
215   public boolean hasGapColour()
216   {
217     return false;
218   }
219 }