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