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