Merge branch 'feature/2588' into merge/develop_feature/2588_JAL-2588
[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   /**
96    * Find a colour without an index in a sequence
97    */
98   public Color findColour(char c)
99   {
100     Color colour = Color.white;
101
102     if (colors != null && symbolIndex != null && c < symbolIndex.length
103             && symbolIndex[c] < colors.length)
104     {
105       colour = colors[symbolIndex[c]];
106     }
107
108     return colour;
109   }
110
111   /**
112    * Default is to call the overloaded method that ignores consensus. A colour
113    * scheme that depends on consensus (for example, Blosum62), should override
114    * this method instead.
115    */
116   @Override
117   public Color findColour(char c, int j, SequenceI seq,
118           String consensusResidue, float pid)
119   {
120     return findColour(c, j, seq);
121   }
122
123   /**
124    * Default implementation looks up the residue colour in a fixed scheme, or
125    * returns White if not found. Override this method for a colour scheme that
126    * depends on the column position or sequence.
127    * 
128    * @param c
129    * @param j
130    * @param seq
131    * @return
132    */
133   protected Color findColour(char c, int j, SequenceI seq)
134   {
135     return findColour(c);
136   }
137
138   @Override
139   public void alignmentChanged(AnnotatedCollectionI alignment,
140           Map<SequenceI, SequenceCollectionI> hiddenReps)
141   {
142   }
143
144   /**
145    * Answers false if the colour scheme is nucleotide or peptide specific, and
146    * the data does not match, else true. Override to modify or extend this test
147    * as required.
148    */
149   @Override
150   public boolean isApplicableTo(AnnotatedCollectionI ac)
151   {
152     if (!isPeptideSpecific() && !isNucleotideSpecific())
153     {
154       return true;
155     }
156     if (ac == null)
157     {
158       return true;
159     }
160     /*
161      * pop-up menu on selection group before group created
162      * (no alignment context)
163      */
164     // TODO: add nucleotide flag to SequenceGroup?
165     if (ac instanceof SequenceGroup && ac.getContext() == null)
166     {
167       return true;
168     }
169
170     /*
171      * inspect the data context (alignment) for residue type
172      */
173     boolean nucleotide = ac.isNucleotide();
174
175     /*
176      * does data type match colour scheme type?
177      */
178     return (nucleotide && isNucleotideSpecific())
179             || (!nucleotide && isPeptideSpecific());
180   }
181
182   /**
183    * Answers true if the colour scheme is normally only for peptide data
184    * 
185    * @return
186    */
187   public boolean isPeptideSpecific()
188   {
189     return false;
190   }
191
192   /**
193    * Answers true if the colour scheme is normally only for nucleotide data
194    * 
195    * @return
196    */
197   public boolean isNucleotideSpecific()
198   {
199     return false;
200   }
201
202   /**
203    * Default method returns true. Override this to return false in colour
204    * schemes that are not determined solely by the sequence symbol.
205    */
206   @Override
207   public boolean isSimple()
208   {
209     return true;
210   }
211
212   /**
213    * Default method returns false. Override this to return true in colour
214    * schemes that have a colour associated with gap residues.
215    */
216   @Override
217   public boolean hasGapColour()
218   {
219     return false;
220   }
221 }