patch to fix occasional arrayoutofbounds exception when working with hidden columns...
[jalview.git] / src / jalview / schemes / AnnotationColourGradient.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)
3  * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  * 
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19 package jalview.schemes;
20
21 import java.awt.*;
22
23 import jalview.datamodel.*;
24
25 public class AnnotationColourGradient extends ResidueColourScheme
26 {
27   public static int NO_THRESHOLD = -1;
28
29   public static int BELOW_THRESHOLD = 0;
30
31   public static int ABOVE_THRESHOLD = 1;
32
33   public AlignmentAnnotation annotation;
34
35   int aboveAnnotationThreshold = -1;
36
37   public boolean thresholdIsMinMax = false;
38
39   GraphLine annotationThreshold;
40
41   float r1, g1, b1, rr, gg, bb, dr, dg, db;
42
43   ColourSchemeI colourScheme;
44
45   public boolean predefinedColours = false;
46
47   /**
48    * Creates a new AnnotationColourGradient object.
49    */
50   public AnnotationColourGradient(AlignmentAnnotation annotation,
51           ColourSchemeI originalColour, int aboveThreshold)
52   {
53     if (originalColour instanceof AnnotationColourGradient)
54     {
55       colourScheme = ((AnnotationColourGradient) originalColour).colourScheme;
56     }
57     else
58     {
59       colourScheme = originalColour;
60     }
61
62     this.annotation = annotation;
63
64     aboveAnnotationThreshold = aboveThreshold;
65
66     if (aboveThreshold != NO_THRESHOLD && annotation.threshold != null)
67     {
68       annotationThreshold = annotation.threshold;
69     }
70   }
71
72   /**
73    * Creates a new AnnotationColourGradient object.
74    */
75   public AnnotationColourGradient(AlignmentAnnotation annotation,
76           Color minColour, Color maxColour, int aboveThreshold)
77   {
78     this.annotation = annotation;
79
80     aboveAnnotationThreshold = aboveThreshold;
81
82     if (aboveThreshold != NO_THRESHOLD && annotation.threshold != null)
83     {
84       annotationThreshold = annotation.threshold;
85     }
86
87     r1 = minColour.getRed();
88     g1 = minColour.getGreen();
89     b1 = minColour.getBlue();
90
91     rr = maxColour.getRed() - r1;
92     gg = maxColour.getGreen() - g1;
93     bb = maxColour.getBlue() - b1;
94   }
95
96   public String getAnnotation()
97   {
98     return annotation.label;
99   }
100
101   public int getAboveThreshold()
102   {
103     return aboveAnnotationThreshold;
104   }
105
106   public float getAnnotationThreshold()
107   {
108     if (annotationThreshold == null)
109     {
110       return 0;
111     }
112     else
113     {
114       return annotationThreshold.value;
115     }
116   }
117
118   public ColourSchemeI getBaseColour()
119   {
120     return colourScheme;
121   }
122
123   public Color getMinColour()
124   {
125     return new Color((int) r1, (int) g1, (int) b1);
126   }
127
128   public Color getMaxColour()
129   {
130     return new Color((int) (r1 + rr), (int) (g1 + gg), (int) (b1 + bb));
131   }
132
133   /**
134    * DOCUMENT ME!
135    * 
136    * @param n
137    *                DOCUMENT ME!
138    * 
139    * @return DOCUMENT ME!
140    */
141   public Color findColour(char c)
142   {
143     return Color.red;
144   }
145
146   /**
147    * DOCUMENT ME!
148    * 
149    * @param n
150    *                DOCUMENT ME!
151    * @param j
152    *                DOCUMENT ME!
153    * 
154    * @return DOCUMENT ME!
155    */
156   public Color findColour(char c, int j)
157   {
158     Color currentColour = Color.white;
159
160     if ((threshold == 0) || aboveThreshold(c, j))
161     {
162       if (j < annotation.annotations.length
163               && annotation.annotations[j] != null
164               && !jalview.util.Comparison.isGap(c))
165       {
166
167         if (predefinedColours)
168         {
169           if (annotation.annotations[j].colour != null)
170             return annotation.annotations[j].colour;
171           else
172             return currentColour;
173         }
174
175         if (aboveAnnotationThreshold == NO_THRESHOLD
176                 || (annotationThreshold != null
177                         && aboveAnnotationThreshold == ABOVE_THRESHOLD && annotation.annotations[j].value >= annotationThreshold.value)
178                 || (annotationThreshold != null
179                         && aboveAnnotationThreshold == BELOW_THRESHOLD && annotation.annotations[j].value <= annotationThreshold.value))
180         {
181
182           float range = 1f;
183           if (thresholdIsMinMax
184                   && annotation.threshold != null
185                   && aboveAnnotationThreshold == ABOVE_THRESHOLD
186                   && annotation.annotations[j].value > annotation.threshold.value)
187           {
188             range = (annotation.annotations[j].value - annotation.threshold.value)
189                     / (annotation.graphMax - annotation.threshold.value);
190           }
191           else if (thresholdIsMinMax && annotation.threshold != null
192                   && aboveAnnotationThreshold == BELOW_THRESHOLD
193                   && annotation.annotations[j].value > annotation.graphMin)
194           {
195             range = (annotation.annotations[j].value - annotation.graphMin)
196                     / (annotation.threshold.value - annotation.graphMin);
197           }
198           else
199           {
200             range = (annotation.annotations[j].value - annotation.graphMin)
201                     / (annotation.graphMax - annotation.graphMin);
202           }
203
204           if (colourScheme != null)
205           {
206             currentColour = colourScheme.findColour(c, j);
207           }
208           else if (range != 0)
209           {
210             dr = rr * range + r1;
211             dg = gg * range + g1;
212             db = bb * range + b1;
213
214             currentColour = new Color((int) dr, (int) dg, (int) db);
215           }
216         }
217       }
218     }
219
220     if (conservationColouring)
221     {
222       currentColour = applyConservation(currentColour, j);
223     }
224
225     return currentColour;
226   }
227 }