2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3 * Copyright (C) 2014 The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
21 package jalview.schemes;
23 import jalview.datamodel.AlignmentAnnotation;
24 import jalview.datamodel.AlignmentI;
25 import jalview.datamodel.AnnotatedCollectionI;
26 import jalview.datamodel.Annotation;
27 import jalview.datamodel.GraphLine;
28 import jalview.datamodel.SequenceCollectionI;
29 import jalview.datamodel.SequenceI;
31 import java.awt.Color;
32 import java.util.IdentityHashMap;
35 public class AnnotationColourGradient extends FollowerColourScheme
37 public static final int NO_THRESHOLD = -1;
39 public static final int BELOW_THRESHOLD = 0;
41 public static final int ABOVE_THRESHOLD = 1;
43 public AlignmentAnnotation annotation;
45 int aboveAnnotationThreshold = -1;
47 public boolean thresholdIsMinMax = false;
49 GraphLine annotationThreshold;
51 float r1, g1, b1, rr, gg, bb;
53 private boolean predefinedColours = false;
55 private boolean seqAssociated = false;
58 * false if the scheme was constructed without a minColour and maxColour used
59 * to decide if existing colours should be taken from annotation elements when
62 private boolean noGradient = false;
63 IdentityHashMap<SequenceI, AlignmentAnnotation> seqannot = null;
66 public ColourSchemeI applyTo(AnnotatedCollectionI sg,
67 Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
69 AnnotationColourGradient acg = new AnnotationColourGradient(annotation,
70 colourScheme, aboveAnnotationThreshold);
71 acg.thresholdIsMinMax = thresholdIsMinMax;
72 acg.annotationThreshold = (annotationThreshold == null) ? null
73 : new GraphLine(annotationThreshold);
80 acg.predefinedColours = predefinedColours;
81 acg.seqAssociated = seqAssociated;
82 acg.noGradient = noGradient;
87 * Creates a new AnnotationColourGradient object.
89 public AnnotationColourGradient(AlignmentAnnotation annotation,
90 ColourSchemeI originalColour, int aboveThreshold)
92 if (originalColour instanceof AnnotationColourGradient)
94 colourScheme = ((AnnotationColourGradient) originalColour).colourScheme;
98 colourScheme = originalColour;
101 this.annotation = annotation;
103 aboveAnnotationThreshold = aboveThreshold;
105 if (aboveThreshold != NO_THRESHOLD && annotation.threshold != null)
107 annotationThreshold = annotation.threshold;
109 // clear values so we don't get weird black bands...
121 * Creates a new AnnotationColourGradient object.
123 public AnnotationColourGradient(AlignmentAnnotation annotation,
124 Color minColour, Color maxColour, int aboveThreshold)
126 this.annotation = annotation;
128 aboveAnnotationThreshold = aboveThreshold;
130 if (aboveThreshold != NO_THRESHOLD && annotation.threshold != null)
132 annotationThreshold = annotation.threshold;
135 r1 = minColour.getRed();
136 g1 = minColour.getGreen();
137 b1 = minColour.getBlue();
139 rr = maxColour.getRed() - r1;
140 gg = maxColour.getGreen() - g1;
141 bb = maxColour.getBlue() - b1;
147 public void alignmentChanged(AnnotatedCollectionI alignment,
148 Map<SequenceI, SequenceCollectionI> hiddenReps)
150 super.alignmentChanged(alignment, hiddenReps);
152 if (seqAssociated && annotation.getCalcId() != null)
154 if (seqannot != null)
160 seqannot = new IdentityHashMap<SequenceI, AlignmentAnnotation>();
162 // resolve the context containing all the annotation for the sequence
163 AnnotatedCollectionI alcontext = alignment instanceof AlignmentI ? alignment
164 : alignment.getContext();
165 for (AlignmentAnnotation alan : alcontext.findAnnotation(annotation
168 if (alan.sequenceRef != null
169 && (alan.label != null && annotation != null && alan.label
170 .equals(annotation.label)))
172 seqannot.put(alan.sequenceRef, alan);
178 public String getAnnotation()
180 return annotation.label;
183 public int getAboveThreshold()
185 return aboveAnnotationThreshold;
188 public float getAnnotationThreshold()
190 if (annotationThreshold == null)
196 return annotationThreshold.value;
200 public Color getMinColour()
202 return new Color((int) r1, (int) g1, (int) b1);
205 public Color getMaxColour()
207 return new Color((int) (r1 + rr), (int) (g1 + gg), (int) (b1 + bb));
216 * @return DOCUMENT ME!
218 public Color findColour(char c)
231 * @return DOCUMENT ME!
234 public Color findColour(char c, int j, SequenceI seq)
236 Color currentColour = Color.white;
237 AlignmentAnnotation annotation = (seqAssociated ? seqannot.get(seq)
239 if (annotation == null)
241 return currentColour;
243 if ((threshold == 0) || aboveThreshold(c, j))
245 if (annotation.annotations != null
246 && j < annotation.annotations.length
247 && annotation.annotations[j] != null
248 && !jalview.util.Comparison.isGap(c))
250 Annotation aj = annotation.annotations[j];
251 // 'use original colours' => colourScheme != null
252 // -> look up colour to be used
253 // predefined colours => preconfigured shading
254 // -> only use original colours reference if thresholding enabled &
256 // annotation.hasIcons => null or black colours replaced with glyph
258 // -> reuse original colours if present
259 // -> if thresholding enabled then return colour on non-whitespace glyph
261 if (aboveAnnotationThreshold == NO_THRESHOLD
262 || (annotationThreshold != null && (aboveAnnotationThreshold == ABOVE_THRESHOLD ? aj.value >= annotationThreshold.value
263 : aj.value <= annotationThreshold.value)))
265 if (predefinedColours && aj.colour != null)
267 currentColour = aj.colour;
269 else if (annotation.hasIcons
270 && annotation.graph == AlignmentAnnotation.NO_GRAPH)
272 if (aj.secondaryStructure > ' ' && aj.secondaryStructure != '.'
273 && aj.secondaryStructure != '-')
275 if (colourScheme != null)
277 currentColour = colourScheme.findColour(c, j, seq);
281 currentColour = annotation.annotations[j].secondaryStructure == 'H' ? jalview.renderer.AnnotationRenderer.HELIX_COLOUR
282 : annotation.annotations[j].secondaryStructure == 'E' ? jalview.renderer.AnnotationRenderer.SHEET_COLOUR
283 : jalview.renderer.AnnotationRenderer.STEM_COLOUR;
294 if (colourScheme != null)
296 currentColour = colourScheme.findColour(c, j, seq);
300 if (aj.colour != null)
302 currentColour = aj.colour;
310 if (thresholdIsMinMax
311 && annotation.threshold != null
312 && aboveAnnotationThreshold == ABOVE_THRESHOLD
313 && annotation.annotations[j].value >= annotation.threshold.value)
315 range = (annotation.annotations[j].value - annotation.threshold.value)
316 / (annotation.graphMax - annotation.threshold.value);
318 else if (thresholdIsMinMax
319 && annotation.threshold != null
320 && aboveAnnotationThreshold == BELOW_THRESHOLD
321 && annotation.annotations[j].value >= annotation.graphMin)
323 range = (annotation.annotations[j].value - annotation.graphMin)
324 / (annotation.threshold.value - annotation.graphMin);
328 range = (annotation.annotations[j].value - annotation.graphMin)
329 / (annotation.graphMax - annotation.graphMin);
332 int dr = (int) (rr * range + r1), dg = (int) (gg * range + g1), db = (int) (bb
335 currentColour = new Color(dr, dg, db);
339 if (conservationColouring)
341 currentColour = applyConservation(currentColour, j);
345 return currentColour;
348 public boolean isPredefinedColours()
350 return predefinedColours;
353 public void setPredefinedColours(boolean predefinedColours)
355 this.predefinedColours = predefinedColours;
358 public boolean isSeqAssociated()
360 return seqAssociated;
363 public void setSeqAssociated(boolean sassoc)
365 seqAssociated = sassoc;