78e850bacd01ba858e7357ab074005c8d8baa0a2
[jalview.git] / src / jalview / schemes / AnnotationColourGradient.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3  * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, 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         seqannot.clear();
116       } else {
117         seqannot=new IdentityHashMap<SequenceI, AlignmentAnnotation>();
118       }
119       for (AlignmentAnnotation alan : alignment.findAnnotation(annotation
120               .getCalcId()))
121       {
122         if (alan.sequenceRef != null
123                 && (alan.label != null && annotation != null && alan.label
124                         .equals(annotation.label)))
125         {
126           seqannot.put(alan.sequenceRef, alan);
127         }
128       }
129     }
130   }
131
132   public String getAnnotation()
133   {
134     return annotation.label;
135   }
136
137   public int getAboveThreshold()
138   {
139     return aboveAnnotationThreshold;
140   }
141
142   public float getAnnotationThreshold()
143   {
144     if (annotationThreshold == null)
145     {
146       return 0;
147     }
148     else
149     {
150       return annotationThreshold.value;
151     }
152   }
153
154   public ColourSchemeI getBaseColour()
155   {
156     return colourScheme;
157   }
158
159   public Color getMinColour()
160   {
161     return new Color((int) r1, (int) g1, (int) b1);
162   }
163
164   public Color getMaxColour()
165   {
166     return new Color((int) (r1 + rr), (int) (g1 + gg), (int) (b1 + bb));
167   }
168
169   /**
170    * DOCUMENT ME!
171    * 
172    * @param n
173    *          DOCUMENT ME!
174    * 
175    * @return DOCUMENT ME!
176    */
177   public Color findColour(char c)
178   {
179     return Color.red;
180   }
181
182   /**
183    * DOCUMENT ME!
184    * 
185    * @param n
186    *          DOCUMENT ME!
187    * @param j
188    *          DOCUMENT ME!
189    * 
190    * @return DOCUMENT ME!
191    */
192   @Override
193   public Color findColour(char c, int j, SequenceI seq)
194   {
195     Color currentColour = Color.white;
196     AlignmentAnnotation annotation=(seqAssociated ? seqannot.get(seq):this.annotation);
197     if (annotation==null)
198     {
199       return currentColour;
200     }
201     if ((threshold == 0) || aboveThreshold(c, j))
202     {
203       if (j < annotation.annotations.length
204               && annotation.annotations[j] != null
205               && !jalview.util.Comparison.isGap(c))
206       {
207
208         if (predefinedColours)
209         {
210           if (annotation.annotations[j].colour != null)
211             return annotation.annotations[j].colour;
212           else
213             return currentColour;
214         }
215
216         if (aboveAnnotationThreshold == NO_THRESHOLD
217                 || (annotationThreshold != null
218                         && aboveAnnotationThreshold == ABOVE_THRESHOLD && annotation.annotations[j].value >= annotationThreshold.value)
219                 || (annotationThreshold != null
220                         && aboveAnnotationThreshold == BELOW_THRESHOLD && annotation.annotations[j].value <= annotationThreshold.value))
221         {
222
223           float range = 1f;
224           if (thresholdIsMinMax
225                   && annotation.threshold != null
226                   && aboveAnnotationThreshold == ABOVE_THRESHOLD
227                   && annotation.annotations[j].value > annotation.threshold.value)
228           {
229             range = (annotation.annotations[j].value - annotation.threshold.value)
230                     / (annotation.graphMax - annotation.threshold.value);
231           }
232           else if (thresholdIsMinMax && annotation.threshold != null
233                   && aboveAnnotationThreshold == BELOW_THRESHOLD
234                   && annotation.annotations[j].value > annotation.graphMin)
235           {
236             range = (annotation.annotations[j].value - annotation.graphMin)
237                     / (annotation.threshold.value - annotation.graphMin);
238           }
239           else
240           {
241             range = (annotation.annotations[j].value - annotation.graphMin)
242                     / (annotation.graphMax - annotation.graphMin);
243           }
244
245           if (colourScheme != null)
246           {
247             currentColour = colourScheme.findColour(c, j, seq);
248           }
249           else if (range != 0)
250           {
251             dr = rr * range + r1;
252             dg = gg * range + g1;
253             db = bb * range + b1;
254
255             currentColour = new Color((int) dr, (int) dg, (int) db);
256           }
257         }
258       }
259     }
260
261     if (conservationColouring)
262     {
263       currentColour = applyConservation(currentColour, j);
264     }
265
266     return currentColour;
267   }
268
269   public boolean isSeqAssociated()
270   {
271     return seqAssociated;
272   }
273
274   public void setSeqAssociated(boolean sassoc)
275   {
276     seqAssociated = sassoc;
277   }
278 }