pir format ambiguity and todo regarding 'format override' parameter
[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   public boolean getTolow()
109   {
110     return tolow;
111   }
112   public void setTolow(boolean tolower)
113   {
114     tolow = tolower;
115   }
116   public boolean isColored(SequenceFeature feature)
117   {
118     float val = feature.getScore();
119     if (val==Float.NaN)
120     {
121       return true;
122     }
123     if (this.thresholdState==AnnotationColourGradient.NO_THRESHOLD)
124     {
125       return true;
126     }
127     if (this.thrsh==Float.NaN)
128     {
129       return true;
130     }
131     boolean rtn = thresholdState==AnnotationColourGradient.ABOVE_THRESHOLD;
132     if (val<=thrsh)
133     {
134       return !rtn; //  ? !tolow : tolow;
135     } else {
136       return rtn; //  ? tolow : !tolow;
137     }
138   }
139   /**
140    * default implementor of a getColourFromString method.
141    * TODO: abstract an interface enabling pluggable colour from string
142    */
143   private UserColourScheme ucs = null;
144   private boolean colourByLabel=true;
145   /**
146    * 
147    * @return true if colourByLabel style is set
148    */
149   public boolean isColourByLabel()
150   {
151     return colourByLabel;
152   }
153   /**
154    * @param colourByLabel the colourByLabel to set
155    */
156   public void setColourByLabel(boolean colourByLabel)
157   {
158     this.colourByLabel = colourByLabel;
159   }
160   public Color findColor(SequenceFeature feature)
161   {
162     if (colourByLabel)
163     {
164       //TODO: allow user defined feature label colourschemes. Colour space is {type,regex,%anytype%}x{description string, regex, keyword}
165       if (ucs==null)
166       {
167         ucs = new UserColourScheme();
168       }
169       return ucs.createColourFromName(feature.getDescription());
170     }
171     if (range==0.0)
172     {
173       return getMaxColor();
174     }
175     float scr = feature.getScore();
176     if (scr==Float.NaN)
177     {
178       return getMinColor();
179     }
180     float scl = (scr-base)/range;
181     if (tolow) { scl = -scl; }
182     if (scl<0f) { scl = 0f; }
183     if (scl>1f) { scl = 1f; }
184     return new Color(lr+scl*dr,lg+scl*dg,lb+scl*db);
185   }
186   public void setThresh(float value)
187   {
188     thrsh = value;
189   }
190   public float getThresh() {
191     return thrsh;
192   }
193   public void setThreshType(int aboveThreshold)
194   {
195     thresholdState = aboveThreshold;
196   }
197   public int getThreshType()
198   {
199     return thresholdState;
200   }
201   public float getMax()
202   {
203     // regenerate the original values passed in to the constructor
204     return (tolow) ? base : (base + range);
205   }
206   public float getMin()
207   {
208     // regenerate the original value passed in to the constructor
209     return (tolow) ? (base+range) : base;
210   }
211   public boolean isAutoScale()
212   {
213     return autoScale;
214   }
215   public void setAutoScaled(boolean autoscale) {
216     autoScale = autoscale;
217   }
218   /**
219    * update the base and range appropriatly for the given minmax range  
220    * @param a float[] {min,max} array containing minmax range for the associated score values
221    */
222   public void updateBounds(float min,float max) 
223   {
224     if (max<min)
225     {
226       base = max;
227       range = min-max;
228       tolow=true;
229     } else {
230       base = min;
231       range = max-min;
232       tolow=false;
233     }
234   }
235 }