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