added graduated colourscheme support for feature file
[jalview.git] / src / jalview / schemes / GraduatedColor.java
1 /**
2  * 
3  */
4 package jalview.schemes;
5
6 import jalview.datamodel.SequenceFeature;
7
8 import java.awt.Color;
9
10 /**
11  * Value and/or thresholded colour scale used for colouring by annotation and feature score
12  * @author JimP
13  *
14  */
15 public class GraduatedColor
16 {
17   int thresholdState = AnnotationColourGradient.NO_THRESHOLD; // or ABOVE_THRESHOLD or BELOW_THRESHOLD
18   float lr,lg,lb,dr,dg,db;
19   /**
20    * linear scaling parameters, base, minimum colour threshold, range of linear scale from lower to upper
21    */
22   float base,range,thrsh;
23   /**
24    * when true, colour from u to u-d rather than u to u+d
25    */
26   boolean tolow=false;
27   /**
28    * when false, min/max range has been manually set so should not be dynamically adjusted.
29    */
30   boolean autoScale = true;
31   /**
32    * construct a graduatedColor object from simple parameters
33    * @param low
34    * @param high
35    * @param min
36    * @param max
37    * color low->high from min->max
38    */
39   public GraduatedColor(Color low,Color high, float min,float max)
40   {
41     thrsh = Float.NaN;
42     tolow = min>=max;
43     lr = low.getRed()/255f;
44     lg = low.getGreen()/255f;
45     lb = low.getBlue()/255f;
46     dr = (high.getRed()/255f)-lr;
47     dg = (high.getGreen()/255f)-lg;
48     db = (high.getBlue()/255f)-lb;
49     if (tolow)
50     {
51       base = max;
52       range = min-max;
53     } else {
54       base = min;
55       range = max-min;
56     }
57   }
58   public GraduatedColor(GraduatedColor oldcs)
59   {
60     lr = oldcs.lr;
61     lg = oldcs.lg;
62     lb = oldcs.lb;
63     dr = oldcs.dr;
64     dg = oldcs.dg;
65     db = oldcs.db;
66     base = oldcs.base;
67     range = oldcs.range;
68     tolow = oldcs.tolow;
69     thresholdState = oldcs.thresholdState;
70     thrsh = oldcs.thrsh;
71     autoScale = oldcs.autoScale;
72   }
73   /**
74    * make a new gradient from an old one with a different scale range
75    * @param oldcs
76    * @param min
77    * @param max
78    */
79   public GraduatedColor(GraduatedColor oldcs, float min, float max)
80   {
81     this(oldcs);
82     updateBounds(min, max);
83   }
84   public Color getMinColor()
85   {
86     return new Color(lr,lg,lb);
87   }
88   public Color getMaxColor()
89   {
90     return new Color(lr+dr,lg+dg,lb+db);
91   }
92   public boolean getTolow()
93   {
94     return tolow;
95   }
96   public void setTolow(boolean tolower)
97   {
98     tolow = tolower;
99   }
100   public boolean isColored(SequenceFeature feature)
101   {
102     float val = feature.getScore();
103     if (val==Float.NaN)
104     {
105       return true;
106     }
107     if (this.thresholdState==AnnotationColourGradient.NO_THRESHOLD)
108     {
109       return true;
110     }
111     if (this.thrsh==Float.NaN)
112     {
113       return true;
114     }
115     boolean rtn = thresholdState==AnnotationColourGradient.ABOVE_THRESHOLD;
116     if (val<=thrsh)
117     {
118       return !rtn; //  ? !tolow : tolow;
119     } else {
120       return rtn; //  ? tolow : !tolow;
121     }
122   }
123   public Color findColor(SequenceFeature feature)
124   {     
125     if (range==0.0)
126     {
127       return getMaxColor();
128     }
129     float scr = feature.getScore();
130     if (scr==Float.NaN)
131     {
132       return getMinColor();
133     }
134     float scl = (scr-base)/range;
135     if (tolow) { scl = -scl; }
136     if (scl<0f) { scl = 0f; }
137     if (scl>1f) { scl = 1f; }
138     return new Color(lr+scl*dr,lg+scl*dg,lb+scl*db);
139   }
140   public void setThresh(float value)
141   {
142     thrsh = value;
143   }
144   public float getThresh() {
145     return thrsh;
146   }
147   public void setThreshType(int aboveThreshold)
148   {
149     thresholdState = aboveThreshold;
150   }
151   public int getThreshType()
152   {
153     return thresholdState;
154   }
155   public float getMax()
156   {
157     // regenerate the original values passed in to the constructor
158     return (tolow) ? base : (base + range);
159   }
160   public float getMin()
161   {
162     // regenerate the original value passed in to the constructor
163     return (tolow) ? (base+range) : base;
164   }
165   public boolean isAutoScale()
166   {
167     return autoScale;
168   }
169   public void setAutoScaled(boolean autoscale) {
170     autoScale = autoscale;
171   }
172   /**
173    * update the base and range appropriatly for the given minmax range  
174    * @param a float[] {min,max} array containing minmax range for the associated score values
175    */
176   public void updateBounds(float min,float max) 
177   {
178     if (max<min)
179     {
180       base = max;
181       range = min-max;
182       tolow=true;
183     } else {
184       base = min;
185       range = max-min;
186       tolow=false;
187     }
188   }
189 }