apply gpl development license
[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   }
88   /**
89    * make a new gradient from an old one with a different scale range
90    * @param oldcs
91    * @param min
92    * @param max
93    */
94   public GraduatedColor(GraduatedColor oldcs, float min, float max)
95   {
96     this(oldcs);
97     updateBounds(min, max);
98   }
99   public Color getMinColor()
100   {
101     return new Color(lr,lg,lb);
102   }
103   public Color getMaxColor()
104   {
105     return new Color(lr+dr,lg+dg,lb+db);
106   }
107   public boolean getTolow()
108   {
109     return tolow;
110   }
111   public void setTolow(boolean tolower)
112   {
113     tolow = tolower;
114   }
115   public boolean isColored(SequenceFeature feature)
116   {
117     float val = feature.getScore();
118     if (val==Float.NaN)
119     {
120       return true;
121     }
122     if (this.thresholdState==AnnotationColourGradient.NO_THRESHOLD)
123     {
124       return true;
125     }
126     if (this.thrsh==Float.NaN)
127     {
128       return true;
129     }
130     boolean rtn = thresholdState==AnnotationColourGradient.ABOVE_THRESHOLD;
131     if (val<=thrsh)
132     {
133       return !rtn; //  ? !tolow : tolow;
134     } else {
135       return rtn; //  ? tolow : !tolow;
136     }
137   }
138   public Color findColor(SequenceFeature feature)
139   {     
140     if (range==0.0)
141     {
142       return getMaxColor();
143     }
144     float scr = feature.getScore();
145     if (scr==Float.NaN)
146     {
147       return getMinColor();
148     }
149     float scl = (scr-base)/range;
150     if (tolow) { scl = -scl; }
151     if (scl<0f) { scl = 0f; }
152     if (scl>1f) { scl = 1f; }
153     return new Color(lr+scl*dr,lg+scl*dg,lb+scl*db);
154   }
155   public void setThresh(float value)
156   {
157     thrsh = value;
158   }
159   public float getThresh() {
160     return thrsh;
161   }
162   public void setThreshType(int aboveThreshold)
163   {
164     thresholdState = aboveThreshold;
165   }
166   public int getThreshType()
167   {
168     return thresholdState;
169   }
170   public float getMax()
171   {
172     // regenerate the original values passed in to the constructor
173     return (tolow) ? base : (base + range);
174   }
175   public float getMin()
176   {
177     // regenerate the original value passed in to the constructor
178     return (tolow) ? (base+range) : base;
179   }
180   public boolean isAutoScale()
181   {
182     return autoScale;
183   }
184   public void setAutoScaled(boolean autoscale) {
185     autoScale = autoscale;
186   }
187   /**
188    * update the base and range appropriatly for the given minmax range  
189    * @param a float[] {min,max} array containing minmax range for the associated score values
190    */
191   public void updateBounds(float min,float max) 
192   {
193     if (max<min)
194     {
195       base = max;
196       range = min-max;
197       tolow=true;
198     } else {
199       base = min;
200       range = max-min;
201       tolow=false;
202     }
203   }
204 }