javadoc
[jalview.git] / src / jalview / schemes / GraduatedColor.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Development Version 2.4.1)
3  * Copyright (C) 2009 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  * 
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19 package jalview.schemes;
20
21 import jalview.datamodel.SequenceFeature;
22
23 import java.awt.Color;
24
25 /**
26  * Value and/or thresholded colour scale used for colouring by annotation and feature score
27  * @author JimP
28  *
29  */
30 public class GraduatedColor
31 {
32   int thresholdState = AnnotationColourGradient.NO_THRESHOLD; // or ABOVE_THRESHOLD or BELOW_THRESHOLD
33   float lr,lg,lb,dr,dg,db;
34   /**
35    * linear scaling parameters, base, minimum colour threshold, range of linear scale from lower to upper
36    */
37   float base,range,thrsh;
38   /**
39    * when true, colour from u to u-d rather than u to u+d
40    */
41   boolean tolow=false;
42   /**
43    * when false, min/max range has been manually set so should not be dynamically adjusted.
44    */
45   boolean autoScale = true;
46   /**
47    * construct a graduatedColor object from simple parameters
48    * @param low
49    * @param high
50    * @param min
51    * @param max
52    * color low->high from min->max
53    */
54   public GraduatedColor(Color low,Color high, float min,float max)
55   {
56     thrsh = Float.NaN;
57     tolow = min>=max;
58     lr = low.getRed()/255f;
59     lg = low.getGreen()/255f;
60     lb = low.getBlue()/255f;
61     dr = (high.getRed()/255f)-lr;
62     dg = (high.getGreen()/255f)-lg;
63     db = (high.getBlue()/255f)-lb;
64     if (tolow)
65     {
66       base = max;
67       range = min-max;
68     } else {
69       base = min;
70       range = max-min;
71     }
72   }
73   public GraduatedColor(GraduatedColor oldcs)
74   {
75     lr = oldcs.lr;
76     lg = oldcs.lg;
77     lb = oldcs.lb;
78     dr = oldcs.dr;
79     dg = oldcs.dg;
80     db = oldcs.db;
81     base = oldcs.base;
82     range = oldcs.range;
83     tolow = oldcs.tolow;
84     thresholdState = oldcs.thresholdState;
85     thrsh = oldcs.thrsh;
86     autoScale = oldcs.autoScale;
87     colourByLabel = oldcs.colourByLabel; 
88   }
89   /**
90    * make a new gradient from an old one with a different scale range
91    * @param oldcs
92    * @param min
93    * @param max
94    */
95   public GraduatedColor(GraduatedColor oldcs, float min, float max)
96   {
97     this(oldcs);
98     updateBounds(min, max);
99   }
100   public Color getMinColor()
101   {
102     return new Color(lr,lg,lb);
103   }
104   public Color getMaxColor()
105   {
106     return new Color(lr+dr,lg+dg,lb+db);
107   }
108   /**
109    * 
110    * @return true if original min/max scale was from high to low
111    */
112   public boolean getTolow()
113   {
114     return tolow;
115   }
116   public void setTolow(boolean tolower)
117   {
118     tolow = tolower;
119   }
120   public boolean isColored(SequenceFeature feature)
121   {
122     float val = feature.getScore();
123     if (val==Float.NaN)
124     {
125       return true;
126     }
127     if (this.thresholdState==AnnotationColourGradient.NO_THRESHOLD)
128     {
129       return true;
130     }
131     if (this.thrsh==Float.NaN)
132     {
133       return true;
134     }
135     boolean rtn = thresholdState==AnnotationColourGradient.ABOVE_THRESHOLD;
136     if (val<=thrsh)
137     {
138       return !rtn; //  ? !tolow : tolow;
139     } else {
140       return rtn; //  ? tolow : !tolow;
141     }
142   }
143   /**
144    * default implementor of a getColourFromString method.
145    * TODO: abstract an interface enabling pluggable colour from string
146    */
147   private UserColourScheme ucs = null;
148   private boolean colourByLabel=true;
149   /**
150    * 
151    * @return true if colourByLabel style is set
152    */
153   public boolean isColourByLabel()
154   {
155     return colourByLabel;
156   }
157   /**
158    * @param colourByLabel the colourByLabel to set
159    */
160   public void setColourByLabel(boolean colourByLabel)
161   {
162     this.colourByLabel = colourByLabel;
163   }
164   public Color findColor(SequenceFeature feature)
165   {
166     if (colourByLabel)
167     {
168       //TODO: allow user defined feature label colourschemes. Colour space is {type,regex,%anytype%}x{description string, regex, keyword}
169       if (ucs==null)
170       {
171         ucs = new UserColourScheme();
172       }
173       return ucs.createColourFromName(feature.getDescription());
174     }
175     if (range==0.0)
176     {
177       return getMaxColor();
178     }
179     float scr = feature.getScore();
180     if (scr==Float.NaN)
181     {
182       return getMinColor();
183     }
184     float scl = (scr-base)/range;
185     if (tolow) { scl = -scl; }
186     if (scl<0f) { scl = 0f; }
187     if (scl>1f) { scl = 1f; }
188     return new Color(lr+scl*dr,lg+scl*dg,lb+scl*db);
189   }
190   public void setThresh(float value)
191   {
192     thrsh = value;
193   }
194   public float getThresh() {
195     return thrsh;
196   }
197   public void setThreshType(int aboveThreshold)
198   {
199     thresholdState = aboveThreshold;
200   }
201   public int getThreshType()
202   {
203     return thresholdState;
204   }
205   public float getMax()
206   {
207     // regenerate the original values passed in to the constructor
208     return (tolow) ? base : (base + range);
209   }
210   public float getMin()
211   {
212     // regenerate the original value passed in to the constructor
213     return (tolow) ? (base+range) : base;
214   }
215   public boolean isAutoScale()
216   {
217     return autoScale;
218   }
219   public void setAutoScaled(boolean autoscale) {
220     autoScale = autoscale;
221   }
222   /**
223    * update the base and range appropriatly for the given minmax range  
224    * @param a float[] {min,max} array containing minmax range for the associated score values
225    */
226   public void updateBounds(float min,float max) 
227   {
228     if (max<min)
229     {
230       base = max;
231       range = min-max;
232       tolow=true;
233     } else {
234       base = min;
235       range = max-min;
236       tolow=false;
237     }
238   }
239 }