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