3bca94b6782c30b3797a57571e0d49834ce41e28
[jalview.git] / src / jalview / schemes / AnnotationColourGradient.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3  * Copyright (C) 2014 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.AlignmentAnnotation;
24 import jalview.datamodel.AlignmentI;
25 import jalview.datamodel.AnnotatedCollectionI;
26 import jalview.datamodel.GraphLine;
27 import jalview.datamodel.SequenceCollectionI;
28 import jalview.datamodel.SequenceI;
29
30 import java.awt.Color;
31 import java.util.IdentityHashMap;
32 import java.util.Map;
33
34 public class AnnotationColourGradient extends FollowerColourScheme
35 {
36   public static final int NO_THRESHOLD = -1;
37
38   public static final int BELOW_THRESHOLD = 0;
39
40   public static final int ABOVE_THRESHOLD = 1;
41
42   public AlignmentAnnotation annotation;
43
44   int aboveAnnotationThreshold = -1;
45
46   public boolean thresholdIsMinMax = false;
47
48   GraphLine annotationThreshold;
49
50   float r1, g1, b1, rr, gg, bb, dr, dg, db;
51
52   private boolean predefinedColours = false;
53
54   private boolean seqAssociated = false;
55
56   IdentityHashMap<SequenceI, AlignmentAnnotation> seqannot = null;
57
58   @Override
59   public ColourSchemeI applyTo(AnnotatedCollectionI sg,
60           Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
61   {
62     AnnotationColourGradient acg = new AnnotationColourGradient(annotation,
63             colourScheme, aboveAnnotationThreshold);
64     acg.thresholdIsMinMax = thresholdIsMinMax;
65     acg.annotationThreshold = (annotationThreshold == null) ? null
66             : new GraphLine(annotationThreshold);
67     acg.r1 = r1;
68     acg.g1 = g1;
69     acg.b1 = b1;
70     acg.rr = rr;
71     acg.gg = gg;
72     acg.bb = bb;
73     acg.dr = dr;
74     acg.dg = dg;
75     acg.db = db;
76     acg.predefinedColours = predefinedColours;
77     acg.seqAssociated = seqAssociated;
78
79     return acg;
80   }
81
82   /**
83    * Creates a new AnnotationColourGradient object.
84    */
85   public AnnotationColourGradient(AlignmentAnnotation annotation,
86           ColourSchemeI originalColour, int aboveThreshold)
87   {
88     if (originalColour instanceof AnnotationColourGradient)
89     {
90       colourScheme = ((AnnotationColourGradient) originalColour).colourScheme;
91     }
92     else
93     {
94       colourScheme = originalColour;
95     }
96
97     this.annotation = annotation;
98
99     aboveAnnotationThreshold = aboveThreshold;
100
101     if (aboveThreshold != NO_THRESHOLD && annotation.threshold != null)
102     {
103       annotationThreshold = annotation.threshold;
104     }
105   }
106
107   /**
108    * Creates a new AnnotationColourGradient object.
109    */
110   public AnnotationColourGradient(AlignmentAnnotation annotation,
111           Color minColour, Color maxColour, int aboveThreshold)
112   {
113     this.annotation = annotation;
114
115     aboveAnnotationThreshold = aboveThreshold;
116
117     if (aboveThreshold != NO_THRESHOLD && annotation.threshold != null)
118     {
119       annotationThreshold = annotation.threshold;
120     }
121
122     r1 = minColour.getRed();
123     g1 = minColour.getGreen();
124     b1 = minColour.getBlue();
125
126     rr = maxColour.getRed() - r1;
127     gg = maxColour.getGreen() - g1;
128     bb = maxColour.getBlue() - b1;
129   }
130
131   @Override
132   public void alignmentChanged(AnnotatedCollectionI alignment,
133           Map<SequenceI, SequenceCollectionI> hiddenReps)
134   {
135     super.alignmentChanged(alignment, hiddenReps);
136
137     if (seqAssociated && annotation.getCalcId() != null)
138     {
139       if (seqannot != null)
140       {
141         seqannot.clear();
142       }
143       else
144       {
145         seqannot = new IdentityHashMap<SequenceI, AlignmentAnnotation>();
146       }
147       // resolve the context containing all the annotation for the sequence
148       AnnotatedCollectionI alcontext = alignment instanceof AlignmentI ? alignment
149               : alignment.getContext();
150       for (AlignmentAnnotation alan : alcontext.findAnnotation(annotation
151               .getCalcId()))
152       {
153         if (alan.sequenceRef != null
154                 && (alan.label != null && annotation != null && alan.label
155                         .equals(annotation.label)))
156         {
157           seqannot.put(alan.sequenceRef, alan);
158         }
159       }
160     }
161   }
162
163   public String getAnnotation()
164   {
165     return annotation.label;
166   }
167
168   public int getAboveThreshold()
169   {
170     return aboveAnnotationThreshold;
171   }
172
173   public float getAnnotationThreshold()
174   {
175     if (annotationThreshold == null)
176     {
177       return 0;
178     }
179     else
180     {
181       return annotationThreshold.value;
182     }
183   }
184
185   public Color getMinColour()
186   {
187     return new Color((int) r1, (int) g1, (int) b1);
188   }
189
190   public Color getMaxColour()
191   {
192     return new Color((int) (r1 + rr), (int) (g1 + gg), (int) (b1 + bb));
193   }
194
195   /**
196    * DOCUMENT ME!
197    * 
198    * @param n
199    *          DOCUMENT ME!
200    * 
201    * @return DOCUMENT ME!
202    */
203   public Color findColour(char c)
204   {
205     return Color.red;
206   }
207
208   /**
209    * DOCUMENT ME!
210    * 
211    * @param n
212    *          DOCUMENT ME!
213    * @param j
214    *          DOCUMENT ME!
215    * 
216    * @return DOCUMENT ME!
217    */
218   @Override
219   public Color findColour(char c, int j, SequenceI seq)
220   {
221     Color currentColour = Color.white;
222     AlignmentAnnotation annotation = (seqAssociated ? seqannot.get(seq)
223             : this.annotation);
224     if (annotation == null)
225     {
226       return currentColour;
227     }
228     if ((threshold == 0) || aboveThreshold(c, j))
229     {
230       if (annotation.annotations != null
231               && j < annotation.annotations.length
232               && annotation.annotations[j] != null
233               && !jalview.util.Comparison.isGap(c))
234       {
235
236         if (annotation.annotations[j].colour != null)
237         {
238           if (predefinedColours || annotation.hasIcons)
239           {
240             return annotation.annotations[j].colour;
241           }
242         }
243         else
244         {
245           if (predefinedColours)
246           {
247             return (annotation.annotations[j].secondaryStructure == 'H' ? jalview.renderer.AnnotationRenderer.HELIX_COLOUR
248                     : annotation.annotations[j].secondaryStructure == 'E' ? jalview.renderer.AnnotationRenderer.SHEET_COLOUR
249                             : annotation.annotations[j].secondaryStructure != ' ' ? jalview.renderer.AnnotationRenderer.STEM_COLOUR
250                                     : currentColour);
251           }
252         }
253         if (aboveAnnotationThreshold == NO_THRESHOLD
254                 || (annotationThreshold != null
255                         && aboveAnnotationThreshold == ABOVE_THRESHOLD && annotation.annotations[j].value >= annotationThreshold.value)
256                 || (annotationThreshold != null
257                         && aboveAnnotationThreshold == BELOW_THRESHOLD && annotation.annotations[j].value <= annotationThreshold.value))
258         {
259
260           float range = 1f;
261           if (thresholdIsMinMax
262                   && annotation.threshold != null
263                   && aboveAnnotationThreshold == ABOVE_THRESHOLD
264                   && annotation.annotations[j].value >= annotation.threshold.value)
265           {
266             range = (annotation.annotations[j].value - annotation.threshold.value)
267                     / (annotation.graphMax - annotation.threshold.value);
268           }
269           else if (thresholdIsMinMax && annotation.threshold != null
270                   && aboveAnnotationThreshold == BELOW_THRESHOLD
271                   && annotation.annotations[j].value >= annotation.graphMin)
272           {
273             range = (annotation.annotations[j].value - annotation.graphMin)
274                     / (annotation.threshold.value - annotation.graphMin);
275           }
276           else
277           {
278             range = (annotation.annotations[j].value - annotation.graphMin)
279                     / (annotation.graphMax - annotation.graphMin);
280           }
281
282           if (colourScheme != null)
283           {
284             currentColour = colourScheme.findColour(c, j, seq);
285           }
286           else
287           {
288             dr = rr * range + r1;
289             dg = gg * range + g1;
290             db = bb * range + b1;
291
292             currentColour = new Color((int) dr, (int) dg, (int) db);
293           }
294         }
295       }
296     }
297
298     if (conservationColouring)
299     {
300       currentColour = applyConservation(currentColour, j);
301     }
302
303     return currentColour;
304   }
305
306   public boolean isPredefinedColours()
307   {
308     return predefinedColours;
309   }
310
311   public void setPredefinedColours(boolean predefinedColours)
312   {
313     this.predefinedColours = predefinedColours;
314   }
315
316   public boolean isSeqAssociated()
317   {
318     return seqAssociated;
319   }
320
321   public void setSeqAssociated(boolean sassoc)
322   {
323     seqAssociated = sassoc;
324   }
325 }