JAL-3215 refactored ScoreColourScheme construction for scriptability
[jalview.git] / src / jalview / schemes / ScoreColourScheme.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ 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.api.AlignViewportI;
24 import jalview.datamodel.AnnotatedCollectionI;
25 import jalview.datamodel.SequenceI;
26 import jalview.util.Comparison;
27
28 import java.awt.Color;
29
30 /**
31  * A base class for colour schemes which define a graduated colour range based
32  * on
33  * <ul>
34  * <li>a minimum colour</li>
35  * <li>a maximum colour</li>
36  * <li>a score assigned to each residue</li>
37  * </ul>
38  */
39 public class ScoreColourScheme extends ResidueColourScheme
40 {
41   String schemeName;
42
43   double min;
44
45   double max;
46
47   Color minColour;
48
49   Color maxColour;
50
51   double[] scores;
52
53   /**
54    * Constructor
55    * 
56    * @param symbolIndex
57    *          a lookup where the index is a char e.g. 'R' or 'r', and the value
58    *          is its position in the colour table lookup
59    * @param scores
60    *          per residue, with indices corresponding to those for colour lookup
61    */
62   public ScoreColourScheme(String name, int[] symbolIndex, double[] scores,
63           Color minColour, Color maxColour)
64   {
65     super(symbolIndex);
66     this.schemeName = name;
67     this.minColour = minColour;
68     this.maxColour = maxColour;
69
70     setMinMax(scores);
71     this.scores = scores;
72
73     int iSize = scores.length;
74     colors = new Color[scores.length];
75     for (int i = 0; i < iSize; i++)
76     {
77       colors[i] = getScoreColour(scores[i]);
78     }
79   }
80
81   /**
82    * Computes a colour for a score by
83    * <ul>
84    * <li>first scaling the score linearly from 0 (minScore) to 1 (maxScore)</li>
85    * <li>then interpolating rgb values from minColour to maxColour</li>
86    * </ul>
87    * This method is used to make colours for residue scores, but may also be
88    * called to generate a colour for an intermediate score value (for example, a
89    * column average).
90    */
91   public Color getScoreColour(double rawScore)
92   {
93     float score = (float) (rawScore - (float) min) / (float) (max - min);
94     score = Math.max(score, 0f);
95     score = Math.min(score, 1f);
96
97     int r = minColour.getRed()
98             + Math.round((maxColour.getRed() - minColour.getRed()) * score);
99     int g = minColour.getGreen()
100             + Math.round(
101                     (maxColour.getGreen() - minColour.getGreen()) * score);
102     int b = minColour.getBlue()
103             + Math.round(
104                     (maxColour.getBlue() - minColour.getBlue()) * score);
105
106     Color c = new Color(r, g, b);
107     return c;
108   }
109
110   /**
111    * Inspects score values and saves the minimum and maximum
112    * 
113    * @param vals
114    */
115   void setMinMax(double[] vals)
116   {
117     double dMin = Double.MAX_VALUE;
118     double dMax = -Double.MAX_VALUE;
119
120     for (int i = 0; i < vals.length - 1; i++)
121     {
122       dMin = Math.min(dMin, vals[i]);
123       dMax = Math.max(dMax, vals[i]);
124     }
125
126     this.min = vals.length == 0 ? 0d : dMin;
127     this.max = vals.length == 0 ? 0d : dMax;
128   }
129
130   @Override
131   public Color findColour(char c, int j, SequenceI seq)
132   {
133     if (Comparison.isGap(c))
134     {
135       return Color.white;
136     }
137     return super.findColour(c);
138   }
139
140   @Override
141   public String getSchemeName()
142   {
143     return schemeName;
144   }
145
146   /**
147    * Returns a new instance of this colour scheme with which the given data may
148    * be coloured
149    */
150   @Override
151   public ColourSchemeI getInstance(AlignViewportI view,
152           AnnotatedCollectionI coll)
153   {
154     return new ScoreColourScheme(schemeName, symbolIndex, scores, minColour,
155             maxColour);
156   }
157 }