729065c596f90ba6236f42acd2180a6d0c3e9a4d
[jalview.git] / src / jalview / schemes / AnnotationColourGradient.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
3  * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
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 of the License, or (at your option) any later version.
10  *  
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 package jalview.schemes;
19
20 import jalview.datamodel.AlignmentAnnotation;
21 import jalview.datamodel.AnnotatedCollectionI;
22 import jalview.datamodel.GraphLine;
23 import jalview.datamodel.SequenceCollectionI;
24 import jalview.datamodel.SequenceI;
25
26 import java.awt.Color;
27 import java.util.IdentityHashMap;
28 import java.util.Map;
29
30 public class AnnotationColourGradient extends ResidueColourScheme
31 {
32   public static final int NO_THRESHOLD = -1;
33
34   public static final int BELOW_THRESHOLD = 0;
35
36   public static final int ABOVE_THRESHOLD = 1;
37
38   public AlignmentAnnotation annotation;
39
40   int aboveAnnotationThreshold = -1;
41
42   public boolean thresholdIsMinMax = false;
43
44   GraphLine annotationThreshold;
45
46   float r1, g1, b1, rr, gg, bb, dr, dg, db;
47
48   ColourSchemeI colourScheme;
49
50   public boolean predefinedColours = false;
51
52   public boolean seqAssociated = false;
53
54   IdentityHashMap<SequenceI, AlignmentAnnotation> seqannot = null;
55
56   /**
57    * Creates a new AnnotationColourGradient object.
58    */
59   public AnnotationColourGradient(AlignmentAnnotation annotation,
60           ColourSchemeI originalColour, int aboveThreshold)
61   {
62     if (originalColour instanceof AnnotationColourGradient)
63     {
64       colourScheme = ((AnnotationColourGradient) originalColour).colourScheme;
65     }
66     else
67     {
68       colourScheme = originalColour;
69     }
70
71     this.annotation = annotation;
72
73     aboveAnnotationThreshold = aboveThreshold;
74
75     if (aboveThreshold != NO_THRESHOLD && annotation.threshold != null)
76     {
77       annotationThreshold = annotation.threshold;
78     }
79   }
80
81   /**
82    * Creates a new AnnotationColourGradient object.
83    */
84   public AnnotationColourGradient(AlignmentAnnotation annotation,
85           Color minColour, Color maxColour, int aboveThreshold)
86   {
87     this.annotation = annotation;
88
89     aboveAnnotationThreshold = aboveThreshold;
90
91     if (aboveThreshold != NO_THRESHOLD && annotation.threshold != null)
92     {
93       annotationThreshold = annotation.threshold;
94     }
95
96     r1 = minColour.getRed();
97     g1 = minColour.getGreen();
98     b1 = minColour.getBlue();
99
100     rr = maxColour.getRed() - r1;
101     gg = maxColour.getGreen() - g1;
102     bb = maxColour.getBlue() - b1;
103   }
104
105   @Override
106   public void alignmentChanged(AnnotatedCollectionI alignment,
107           Map<SequenceI, SequenceCollectionI> hiddenReps)
108   {
109     // TODO Auto-generated method stub
110     super.alignmentChanged(alignment, hiddenReps);
111
112     if (seqAssociated && annotation.getCalcId() != null)
113     {
114       if (seqannot != null)
115       {
116         seqannot.clear();
117       }
118       else
119       {
120         seqannot = new IdentityHashMap<SequenceI, AlignmentAnnotation>();
121       }
122       for (AlignmentAnnotation alan : alignment.findAnnotation(annotation
123               .getCalcId()))
124       {
125         if (alan.sequenceRef != null
126                 && (alan.label != null && annotation != null && alan.label
127                         .equals(annotation.label)))
128         {
129           seqannot.put(alan.sequenceRef, alan);
130         }
131       }
132     }
133   }
134
135   public String getAnnotation()
136   {
137     return annotation.label;
138   }
139
140   public int getAboveThreshold()
141   {
142     return aboveAnnotationThreshold;
143   }
144
145   public float getAnnotationThreshold()
146   {
147     if (annotationThreshold == null)
148     {
149       return 0;
150     }
151     else
152     {
153       return annotationThreshold.value;
154     }
155   }
156
157   public ColourSchemeI getBaseColour()
158   {
159     return colourScheme;
160   }
161
162   public Color getMinColour()
163   {
164     return new Color((int) r1, (int) g1, (int) b1);
165   }
166
167   public Color getMaxColour()
168   {
169     return new Color((int) (r1 + rr), (int) (g1 + gg), (int) (b1 + bb));
170   }
171
172   /**
173    * DOCUMENT ME!
174    * 
175    * @param n
176    *          DOCUMENT ME!
177    * 
178    * @return DOCUMENT ME!
179    */
180   public Color findColour(char c)
181   {
182     return Color.red;
183   }
184
185   /**
186    * DOCUMENT ME!
187    * 
188    * @param n
189    *          DOCUMENT ME!
190    * @param j
191    *          DOCUMENT ME!
192    * 
193    * @return DOCUMENT ME!
194    */
195   @Override
196   public Color findColour(char c, int j, SequenceI seq)
197   {
198     Color currentColour = Color.white;
199     AlignmentAnnotation annotation = (seqAssociated ? seqannot.get(seq)
200             : this.annotation);
201     if (annotation == null)
202     {
203       return currentColour;
204     }
205     if ((threshold == 0) || aboveThreshold(c, j))
206     {
207       if (j < annotation.annotations.length
208               && annotation.annotations[j] != null
209               && !jalview.util.Comparison.isGap(c))
210       {
211
212         if (predefinedColours)
213         {
214           if (annotation.annotations[j].colour != null)
215             return annotation.annotations[j].colour;
216           else
217             return currentColour;
218         }
219
220         if (aboveAnnotationThreshold == NO_THRESHOLD
221                 || (annotationThreshold != null
222                         && aboveAnnotationThreshold == ABOVE_THRESHOLD && annotation.annotations[j].value >= annotationThreshold.value)
223                 || (annotationThreshold != null
224                         && aboveAnnotationThreshold == BELOW_THRESHOLD && annotation.annotations[j].value <= annotationThreshold.value))
225         {
226
227           float range = 1f;
228           if (thresholdIsMinMax
229                   && annotation.threshold != null
230                   && aboveAnnotationThreshold == ABOVE_THRESHOLD
231                   && annotation.annotations[j].value >= annotation.threshold.value)
232           {
233             range = (annotation.annotations[j].value - annotation.threshold.value)
234                     / (annotation.graphMax - annotation.threshold.value);
235           }
236           else if (thresholdIsMinMax && annotation.threshold != null
237                   && aboveAnnotationThreshold == BELOW_THRESHOLD
238                   && annotation.annotations[j].value >= annotation.graphMin)
239           {
240             range = (annotation.annotations[j].value - annotation.graphMin)
241                     / (annotation.threshold.value - annotation.graphMin);
242           }
243           else
244           {
245             range = (annotation.annotations[j].value - annotation.graphMin)
246                     / (annotation.graphMax - annotation.graphMin);
247           }
248
249           if (colourScheme != null)
250           {
251             currentColour = colourScheme.findColour(c, j, seq);
252           }
253           else 
254           {
255             dr = rr * range + r1;
256             dg = gg * range + g1;
257             db = bb * range + b1;
258
259             currentColour = new Color((int) dr, (int) dg, (int) db);
260           }
261         }
262       }
263     }
264
265     if (conservationColouring)
266     {
267       currentColour = applyConservation(currentColour, j);
268     }
269
270     return currentColour;
271   }
272
273   public boolean isSeqAssociated()
274   {
275     return seqAssociated;
276   }
277
278   public void setSeqAssociated(boolean sassoc)
279   {
280     seqAssociated = sassoc;
281   }
282 }