Clover icon

jalviewX

  1. Project Clover database Wed Oct 31 2018 15:13:58 GMT
  2. Package jalview.schemes

File UserColourScheme.java

 

Coverage histogram

../../img/srcFileCovDistChart9.png
12% of files have more coverage

Code metrics

48
100
16
1
359
237
46
0.46
6.25
16
2.88

Classes

Class Line # Actions
UserColourScheme 38 100 46 27
0.8353658383.5%
 

Contributing tests

This file is covered by 11 tests. .

Source view

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.datamodel.AnnotatedCollectionI;
24    import jalview.datamodel.SequenceCollectionI;
25    import jalview.datamodel.SequenceI;
26    import jalview.util.ColorUtils;
27    import jalview.util.StringUtils;
28   
29    import java.awt.Color;
30    import java.util.ArrayList;
31    import java.util.Collections;
32    import java.util.HashMap;
33    import java.util.List;
34    import java.util.Map;
35    import java.util.Map.Entry;
36    import java.util.StringTokenizer;
37   
 
38    public class UserColourScheme extends ResidueColourScheme
39    {
40    /*
41    * lookup (by symbol index) of lower case colours (if configured)
42    */
43    Color[] lowerCaseColours;
44   
45    protected String schemeName;
46   
 
47  5 toggle public UserColourScheme()
48    {
49  5 super(ResidueProperties.aaIndex);
50    }
51   
 
52  8 toggle public UserColourScheme(Color[] newColors)
53    {
54  8 super(ResidueProperties.aaIndex);
55  8 colors = newColors;
56    }
57   
 
58  0 toggle @Override
59    public ColourSchemeI getInstance(AnnotatedCollectionI sg,
60    Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
61    {
62  0 return new UserColourScheme(this);
63    }
64   
65    /**
66    * Copy constructor
67    *
68    * @return
69    */
 
70  0 toggle protected UserColourScheme(UserColourScheme from)
71    {
72  0 this(from.colors);
73  0 schemeName = from.schemeName;
74  0 if (from.lowerCaseColours != null)
75    {
76  0 lowerCaseColours = new Color[from.lowerCaseColours.length];
77  0 System.arraycopy(from.lowerCaseColours, 0, lowerCaseColours, 0,
78    from.lowerCaseColours.length);
79    }
80    }
81   
82    /**
83    * Constructor for an animino acid colour scheme. The colour specification may
84    * be one of
85    * <ul>
86    * <li>an AWT colour name e.g. red</li>
87    * <li>an AWT hex rgb colour e.g. ff2288</li>
88    * <li>residue colours list e.g. D,E=red;K,R,H=0022FF;c=yellow</li>
89    * </ul>
90    *
91    * @param colour
92    */
 
93  5 toggle public UserColourScheme(String colour)
94    {
95  5 super(ResidueProperties.aaIndex);
96   
97  5 if (colour.contains("="))
98    {
99    /*
100    * a list of colours per residue(s)
101    */
102  2 parseAppletParameter(colour);
103  2 return;
104    }
105   
106  3 Color col = ColorUtils.parseColourString(colour);
107   
108  3 if (col == null)
109    {
110  1 System.out.println("Making colour from name: " + colour);
111  1 col = ColorUtils.createColourFromName(colour);
112    }
113   
114  3 setAll(col);
115  3 schemeName = colour;
116    }
117   
118    /**
119    * Sets all symbols to the specified colour
120    *
121    * @param col
122    */
 
123  7 toggle protected void setAll(Color col)
124    {
125  7 if (symbolIndex == null)
126    {
127  0 return;
128    }
129  7 int max = 0;
130  7 for (int index : symbolIndex)
131    {
132  1785 max = Math.max(max, index);
133    }
134  7 colors = new Color[max + 1];
135  175 for (int i = 0; i <= max; i++)
136    {
137  168 colors[i] = col;
138    }
139    }
140   
 
141  0 toggle public Color[] getColours()
142    {
143  0 return colors;
144    }
145   
 
146  0 toggle public Color[] getLowerCaseColours()
147    {
148  0 return lowerCaseColours;
149    }
150   
 
151  3 toggle public void setName(String name)
152    {
153  3 schemeName = name;
154    }
155   
 
156  0 toggle public String getName()
157    {
158  0 return schemeName;
159    }
160   
161    /**
162    * Parse and save residue colours specified as (for example)
163    *
164    * <pre>
165    * D,E=red; K,R,H=0022FF; c=100,50,75
166    * </pre>
167    *
168    * This should be a semi-colon separated list of colours, which may be defined
169    * by colour name, hex value or comma-separated RGB triple. Each colour is
170    * defined for a comma-separated list of amino acid single letter codes. (Note
171    * that this also allows a colour scheme to be defined for ACGT, but not for
172    * U.)
173    *
174    * @param paramValue
175    */
 
176  4 toggle void parseAppletParameter(String paramValue)
177    {
178  4 setAll(Color.white);
179   
180  4 StringTokenizer st = new StringTokenizer(paramValue, ";");
181  4 StringTokenizer st2;
182  4 String token = null, colour, residues;
183  4 try
184    {
185  21 while (st.hasMoreElements())
186    {
187  17 token = st.nextToken().trim();
188  17 residues = token.substring(0, token.indexOf("="));
189  17 colour = token.substring(token.indexOf("=") + 1);
190   
191  17 st2 = new StringTokenizer(residues, " ,");
192  45 while (st2.hasMoreTokens())
193    {
194  28 String residue = st2.nextToken();
195   
196  28 int colIndex = ResidueProperties.aaIndex[residue.charAt(0)];
197  28 if (colIndex == -1)
198    {
199  0 continue;
200    }
201   
202  28 if (residue.equalsIgnoreCase("lowerCase"))
203    {
204  1 if (lowerCaseColours == null)
205    {
206  0 lowerCaseColours = new Color[colors.length];
207    }
208  25 for (int i = 0; i < lowerCaseColours.length; i++)
209    {
210  24 if (lowerCaseColours[i] == null)
211    {
212  22 lowerCaseColours[i] = ColorUtils.parseColourString(colour);
213    }
214    }
215   
216  1 continue;
217    }
218   
219  27 if (residue.equals(residue.toLowerCase()))
220    {
221  6 if (lowerCaseColours == null)
222    {
223  4 lowerCaseColours = new Color[colors.length];
224    }
225  6 lowerCaseColours[colIndex] = ColorUtils
226    .parseColourString(colour);
227    }
228    else
229    {
230  21 colors[colIndex] = ColorUtils.parseColourString(colour);
231    }
232    }
233    }
234    } catch (Exception ex)
235    {
236  0 System.out.println(
237    "Error parsing userDefinedColours:\n" + token + "\n" + ex);
238    }
239   
240    }
241   
 
242  0 toggle public void setLowerCaseColours(Color[] lcolours)
243    {
244  0 lowerCaseColours = lcolours;
245    }
246   
247    /**
248    * Returns the colour for the given residue character. If the residue is
249    * lower-case, and there is a specific colour defined for lower case, that
250    * colour is returned, else the colour for the upper case residue.
251    */
 
252  58 toggle @Override
253    public Color findColour(char c)
254    {
255  58 if ('a' <= c && c <= 'z' && lowerCaseColours != null)
256    {
257  14 Color colour = lowerCaseColours[symbolIndex[c]];
258  14 if (colour != null)
259    {
260  10 return colour;
261    }
262    }
263  48 return super.findColour(c);
264    }
265   
266    /**
267    * Answers the customised name of the colour scheme, if it has one, else "User
268    * Defined"
269    */
 
270  5 toggle @Override
271    public String getSchemeName()
272    {
273  5 if (schemeName != null && schemeName.length() > 0)
274    {
275  1 return schemeName;
276    }
277  4 return ResidueColourScheme.USER_DEFINED;
278    }
279   
280    /**
281    * Generate an applet colour parameter like A,C,D=12ffe9;Q,W=2393fd;w=9178dd
282    *
283    * @return
284    */
 
285  1 toggle public String toAppletParameter()
286    {
287    /*
288    * step 1: build a map from colours to the symbol(s) that have the colour
289    */
290  1 Map<Color, List<String>> colours = new HashMap<>();
291   
292  27 for (char symbol = 'A'; symbol <= 'Z'; symbol++)
293    {
294  26 String residue = String.valueOf(symbol);
295  26 int index = symbolIndex[symbol];
296  26 Color c = colors[index];
297  26 if (c != null && !c.equals(Color.white))
298    {
299  5 if (colours.get(c) == null)
300    {
301  2 colours.put(c, new ArrayList<String>());
302    }
303  5 colours.get(c).add(residue);
304    }
305  26 if (lowerCaseColours != null)
306    {
307  26 c = lowerCaseColours[index];
308  26 if (c != null && !c.equals(Color.white))
309    {
310  1 residue = residue.toLowerCase();
311  1 if (colours.get(c) == null)
312    {
313  1 colours.put(c, new ArrayList<String>());
314    }
315  1 colours.get(c).add(residue);
316    }
317    }
318    }
319   
320    /*
321    * step 2: make a list of { A,G,R=12f9d6 } residues/colour specs
322    */
323  1 List<String> residueColours = new ArrayList<>();
324  1 for (Entry<Color, List<String>> cols : colours.entrySet())
325    {
326  3 boolean first = true;
327  3 StringBuilder sb = new StringBuilder();
328  3 for (String residue : cols.getValue())
329    {
330  6 if (!first)
331    {
332  3 sb.append(",");
333    }
334  6 sb.append(residue);
335  6 first = false;
336    }
337  3 sb.append("=");
338    /*
339    * get color as hex value, dropping the alpha (ff) part
340    */
341  3 String hexString = Integer.toHexString(cols.getKey().getRGB())
342    .substring(2);
343  3 sb.append(hexString);
344  3 residueColours.add(sb.toString());
345    }
346   
347    /*
348    * sort and output
349    */
350  1 Collections.sort(residueColours);
351  1 return StringUtils.listToDelimitedString(residueColours, ";");
352    }
353   
 
354  4 toggle @Override
355    public boolean hasGapColour()
356    {
357  4 return (findColour(' ') != null);
358    }
359    }