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